英文:
How to generate bearer token when clicking on the link in email
问题
当有人点击电子邮件链接时,我想生成一个承载令牌(bearer token),该令牌包含点击电子邮件链接的人的身份信息;如果此人将电子邮件转发给其他人,则承载令牌应在转发的人点击电子邮件链接时包含转发人的身份信息(此处包含身份信息的目的是在服务器端验证该人的身份)。
电子邮件链接被点击时会调用服务调用,它将调用服务并验证承载令牌。
<a href="http://example.com/verify?c=b53kl23d0ko234r5kok32490kdjk2uise">批准</a>
非常感谢任何评论。
英文:
I want to generate bearer token when someone clicked on the email link, this token contains the identity of the person who clicked on the email link and if person forwarded the email to other person then bearer token should contain identity of forwarded person when he click on the email link(purpose of including identity here is validation of person at server side).
Email link contains service call when clicked it will call service and validate bearer token.
<a href="http://example.com/verify?c=b53kl23d0ko234r5kok32490kdjk2uise">Approve</a>
Appreciate any comments here
答案1
得分: 0
我在用户验证OTP后生成令牌。在你的情况下,你不需要验证任何内容。
API方法
public async Task<IActionResult> LoginFunction(
[HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "Account/Login")] HttpRequest req, ILogger log)
{
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
var accountDto = JsonConvert.DeserializeObject<AccountDto>(requestBody);
log.LogInformation($"ValidateOTP for phoneNumber {accountDto.PhoneNumber}");
var isUserValid = await this.accountService.ValidateOTP(accountDto.PhoneNumber, accountDto.OTP);
if (isUserValid)
{
return (ActionResult)new OkObjectResult(BuildToken(accountDto));
}
return (ActionResult)new NotFoundObjectResult("Invalid OTP");
}
private UserToken BuildToken(AccountDto accountDto)
{
var claims = new[]
{
new Claim(ClaimTypes.MobilePhone, accountDto.PhoneNumber)
};
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("LKM3LKM344NKSFN4KJ345N43KJN4KJFNK")); //从配置中读取
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
// 过期时间
var expiration = DateTime.UtcNow.AddYears(1);
JwtSecurityToken token = new JwtSecurityToken(
issuer: AppConstraint.TokenIssuer,
audience: AppConstraint.Audience,
claims: claims,
expires: expiration,
signingCredentials: creds);
return new UserToken()
{
Token = new JwtSecurityTokenHandler().WriteToken(token),
Expiration = expiration
};
}
获得令牌后,你可以将该令牌存储到用户的浏览器中,并随每个请求一起发送。
使用MrAdvice Aspect的自定义授权属性
public class AuthorizedAttribute : Attribute, IMethodAsyncAdvice
{
public async Task Advise(MethodAsyncAdviceContext context)
{
try
{
try
{
HttpRequest request = (HttpRequest)context.Arguments[0];
var tokenString = request.Headers[AppConstraint.Authorization].ToString().Split(' ')[1];
JwtSecurityToken token = new JwtSecurityTokenHandler().ReadJwtToken(tokenString);
if (token.ValidTo <= DateTime.Now)
{
throw new SecurityTokenExpiredException("Token has expired");
}
var claimPrincipal = GetIdentityFromToken(tokenString);
request.HttpContext.User = claimPrincipal;
}
catch
{
context.ReturnValue = Task.FromResult<IActionResult>((ActionResult)new UnauthorizedResult());
return;
}
await context.ProceedAsync(); // 这将调用原始方法
}
catch
{
throw;
}
}
private ClaimsPrincipal GetIdentityFromToken(string token)
{
var tokenParams = new TokenValidationParameters()
{
RequireSignedTokens = true,
ValidAudience = AppConstraint.Audience,
ValidateAudience = true,
ValidIssuer = AppConstraint.TokenIssuer,
ValidateIssuer = true,
ValidateIssuerSigningKey = true,
ValidateLifetime = true,
IssuerSigningKey = new SymmetricSecurityKey(System.Text.Encoding.UTF8.GetBytes("LKM3LKM344NKSFN4KJ345N43KJN4KJFNK"))
};
var handler = new JwtSecurityTokenHandler();
var result = handler.ValidateToken(token, tokenParams, out _);
return result;
}
}
希望这能帮助你生成和验证自己的令牌。
英文:
I'm generating token after the user verifies OTP. In your case, you don't need to verify anything.
API Method
public async Task<IActionResult> LoginFunction(
[HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "Account/Login")] HttpRequest req, ILogger log)
{
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
var accountDto = JsonConvert.DeserializeObject<AccountDto>(requestBody);
log.LogInformation($"ValidateOTP for phoneNumber {accountDto.PhoneNumber}");
var isUserValid = await this.accountService.ValidateOTP(accountDto.PhoneNumber, accountDto.OTP);
if (isUserValid)
{
return (ActionResult)new OkObjectResult(BuildToken(accountDto));
}
return (ActionResult)new NotFoundObjectResult("Invalid OTP");
}
private UserToken BuildToken(AccountDto accountDto)
{
var claims = new[]
{
new Claim(ClaimTypes.MobilePhone, accountDto.PhoneNumber)
};
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("LKM3LKM344NKSFN4KJ345N43KJN4KJFNK")); //read from config
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
// Expiration time
var expiration = DateTime.UtcNow.AddYears(1);
JwtSecurityToken token = new JwtSecurityToken(
issuer: AppConstraint.TokenIssuer,
audience: AppConstraint.Audience,
claims: claims,
expires: expiration,
signingCredentials: creds);
return new UserToken()
{
Token = new JwtSecurityTokenHandler().WriteToken(token),
Expiration = expiration
};
}
Once you will get token you can store that token to the user's browser and send with each request.
Custom Authorize Attribute Using MrAdvice Aspect
public class AuthorizedAttribute : Attribute, IMethodAsyncAdvice
{
public async Task Advise(MethodAsyncAdviceContext context)
{
try
{
try
{
HttpRequest request = (HttpRequest)context.Arguments[0];
var tokenString = request.Headers[AppConstraint.Authorization].ToString().Split(' ')[1];
JwtSecurityToken token = new JwtSecurityTokenHandler().ReadJwtToken(tokenString);
if (token.ValidTo <= DateTime.Now)
{
throw new SecurityTokenExpiredException("Token has expired");
}
var claimPrincipal = GetIdentityFromToken(tokenString);
request.HttpContext.User = claimPrincipal;
}
catch
{
context.ReturnValue = Task.FromResult<IActionResult>((ActionResult)new UnauthorizedResult());
return;
}
await context.ProceedAsync(); // this calls the original method
}
catch
{
throw;
}
}
private ClaimsPrincipal GetIdentityFromToken(string token)
{
var tokenParams = new TokenValidationParameters()
{
RequireSignedTokens = true,
ValidAudience = AppConstraint.Audience,
ValidateAudience = true,
ValidIssuer = AppConstraint.TokenIssuer,
ValidateIssuer = true,
ValidateIssuerSigningKey = true,
ValidateLifetime = true,
IssuerSigningKey = new SymmetricSecurityKey(System.Text.Encoding.UTF8.GetBytes("LKM3LKM344NKSFN4KJ345N43KJN4KJFNK"))
};
var handler = new JwtSecurityTokenHandler();
var result = handler.ValidateToken(token, tokenParams, out _);
return result;
}
}
Hope this will help to generate and verify your own token.
专注分享java语言的经验与见解,让所有开发者获益!
评论