Reputation: 37
I am getting the token but it is not in json
format. I am using a plugin to put all the response in json
format. And It is all working well for all the API's except the gettoken API
[HttpPost("gettoken")]
public IActionResult GetToken([FromBody]TokenRequest Input)
{
var oUser=_userRepository.AuthenticateUser(Input.UserName,Input.Password);
if (oUser!=null)
{
var claimsdata = new[] {
new Claim(ClaimTypes.Name, oUser.UserName),
new Claim(ClaimTypes.Role, oUser.Role)
};
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:SigningKey"]));
int expiryInMinutes = Convert.ToInt32(_configuration["Jwt:ExpiryInMinutes"]);
var signInCred = new SigningCredentials(key, SecurityAlgorithms.HmacSha256Signature);
var token = new JwtSecurityToken(
issuer: _configuration["Jwt:Issuer"],
audience: _configuration["Jwt:Audience"],
expires: DateTime.UtcNow.AddMinutes(expiryInMinutes),
claims: claimsdata,
signingCredentials: new SigningCredentials(key, SecurityAlgorithms.HmacSha256)
);
var tokenString = new JwtSecurityTokenHandler().WriteToken(token);
return Ok(tokenString);
}
return BadRequest("wrong request");
// return View();
}
Upvotes: 0
Views: 4278
Reputation: 302
First of all I would recommend to define a model which will describe your security token the best. Let's say that would be:
class SecurityToken
{
public string Token { get; set; }
public long Expires { get; set; }
}
There you will store your token string in Token prop. And it's expiration date in Expires prop. Of course, these fields are not obligatory.
Then, create your controller. I prefer inheriting ControllerBase
from .NET Core.
[Route("api/v1/[controller]")]
public class SecurityController : ControllerBase
{
[HttpPost]
[Route("[action]")]
public async Task<IActionResult> Authorize([FromBody] AuthData credentials)
{
try
{
var tokenString = await ObtainToken(credentials, out long expires);
return Ok(new SecurityToken() {
Token = tokenString,
Expires = expires
});
}catch(Exception ex)
{
return StatusCode(400, "Fail");
}
}
}
Let me describe it a bit. On the route api/v1/security/authorize passing some 'abstract' credentials data, i.e. user name and password, it would be available to obtain token. Method ObtainToken
is just a sample, not a real method. I supposed it to be async, so the controller's action returns Task<T>
. I used an 'IActionResult' as the more general: we are allowed to return OK(object)
or StatusCode, BadRequest, etc. (ControllerBase methods).
As well you can define something like:
public SecurityToken Authorize([FromBody] AuthData credentials)
{
var tokenString = ObtainToken(credentials, out long expires);
return new SecurityToken
{
Token = tokenString,
Expires = expires
};
}
And it will do the trick!
The thing is that serialization to JSON is accomplished behind the scene and you do not need to do it yourself.
Talking about your code, I thing you can start with to basic things:
return Ok(tokenString)
of your action to return your model.Upvotes: 2
Reputation: 64160
What you have is already an valid JWT token. You need to decode (its just base64) it on the Client side (JavaScript). For validating it, you need a library which will verify the signature with the token to make sure it hasn't been tampered.
The JWT token consists of three parts, separated by a "." (which you can see in the screenshots already): The header, the payload and the signature.
See https://jwt.io for more information. It also contains a list of libraries supporting decoding and veryifing of JWT Tokens on the client side (JavaScript, C# and other languages).
Current examples are jsonwebtoken and @panva/jose for JavaScript/NodeJs
P.S. even a simple "Some string"
is valid json as is null
.
Upvotes: 1