点击电子邮件中的链接时如何生成承载令牌

huangapple 未分类评论54阅读模式
英文:

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&lt;IActionResult&gt; LoginFunction(
        [HttpTrigger(AuthorizationLevel.Anonymous, &quot;post&quot;, Route = &quot;Account/Login&quot;)] HttpRequest req, ILogger log)
    {
        string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
        var accountDto = JsonConvert.DeserializeObject&lt;AccountDto&gt;(requestBody);
        log.LogInformation($&quot;ValidateOTP for phoneNumber {accountDto.PhoneNumber}&quot;);

        var isUserValid = await this.accountService.ValidateOTP(accountDto.PhoneNumber, accountDto.OTP);
        if (isUserValid)
        {
            return (ActionResult)new OkObjectResult(BuildToken(accountDto));
        }
        return (ActionResult)new NotFoundObjectResult(&quot;Invalid OTP&quot;);
    }

private UserToken BuildToken(AccountDto accountDto)
    {
        var claims = new[]
        {
            new Claim(ClaimTypes.MobilePhone, accountDto.PhoneNumber)
        };

        var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(&quot;LKM3LKM344NKSFN4KJ345N43KJN4KJFNK&quot;)); //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(&#39; &#39;)[1];
                JwtSecurityToken token = new JwtSecurityTokenHandler().ReadJwtToken(tokenString);
                if (token.ValidTo &lt;= DateTime.Now)
                {
                    throw new SecurityTokenExpiredException(&quot;Token has expired&quot;);
                }
                var claimPrincipal = GetIdentityFromToken(tokenString);
                request.HttpContext.User = claimPrincipal;
            }
            catch
            {
                context.ReturnValue = Task.FromResult&lt;IActionResult&gt;((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(&quot;LKM3LKM344NKSFN4KJ345N43KJN4KJFNK&quot;))
        };
        var handler = new JwtSecurityTokenHandler();
        var result = handler.ValidateToken(token, tokenParams, out _);
        return result;
    }
}

Hope this will help to generate and verify your own token.

huangapple
  • 本文由 发表于 2020年4月7日 12:18:38
  • 转载请务必保留本文链接:https://java.coder-hub.com/61072783.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定