Обновить токен угловой 8 - PullRequest
1 голос
/ 21 октября 2019

У меня есть приложение, использующее Angular 8, которое работает с ядром .NET. Я хотел бы знать, как я могу обновить токен JWT.

У меня есть интеграция, которая позволяет пользователям проверять и возвращать токен. Этот токен имеет продолжительность 30 минут.

Я хочу добиться того, чтобы из приложения Angular я мог определить, когда токену осталось 5 минут до истечения срока его действия, и, если это так, он переходит квеб-API и генерирует его снова.

Ответы [ 3 ]

1 голос
/ 21 октября 2019

Проверьте эту ссылку Отличное объяснение для обновления токена JWT.

Проверьте код на стороне сервера

Создать токен

        [HttpPost("Authenticate")]
        [AllowAnonymous]
        [ProducesResponseType(StatusCodes.Status400BadRequest)]
        [ProducesResponseType(typeof(TokenResponse), StatusCodes.Status200OK)]
        public async Task<IActionResult> Authenticate([FromBody]LoginModel model)
        {

            // get current user
            var user = await _accountService.FindByEmailAsync(model.Email);

            if (user != null)
            {
                var result = await _accountService.CheckPasswordSignInAsync(user, model.Password, false);

                if (result.Succeeded)
                {
                    // check refresh token delete if exits and recreate new
                    var refreshToken = await _refreshTokenService.GetRefreshToken(user);
                    if (refreshToken != null)
                        await _refreshTokenService.DeleteRefreshToken(refreshToken);

                    var newRefreshToken = new RefreshToken
                    {
                        UserId = user.Id,
                        Token = Guid.NewGuid().ToString(),
                        IssuedUtc = DateTime.Now.ToUniversalTime(),
                        ExpiresUtc = DateTime.Now.ToUniversalTime().AddMinutes(Convert.ToDouble(_appSettings.ExpireMinutesTokenRefresh))
                    };

                    await _refreshTokenService.CreateRefreshToken(newRefreshToken);


                    // generate jwt token
                    var token = GenerateJwtToken(model.Email, user, out DateTime expires);

                    var response = new TokenResponse
                    {
                        AccessToken = token,
                        RefreshToken = newRefreshToken.Token,
                        FirstName = newRefreshToken.User.FirstName,
                        LastName = newRefreshToken.User.LastName,
                        TokenExpiration = expires,
                    };

                    return Ok(response);
                }
                else
                {
                    return BadRequest("Login or password incorrect");
                }
            }
            else
            {
                return BadRequest("Login or password incorrect");
            }
        }

Жетон обновления

        [HttpPost]
        [AllowAnonymous]
        [Route("Token/Refresh")]
        [ProducesResponseType(StatusCodes.Status400BadRequest)]
        [ProducesResponseType(StatusCodes.Status401Unauthorized)]
        [ProducesResponseType(typeof(TokenResponse), StatusCodes.Status200OK)]
        public async Task<IActionResult> RefreshToken([FromBody] RefreshToken refreshToken)
        {
            var refreshTokenFromDatabase = await _refreshTokenService.GetRefreshToken(refreshToken);

            if (refreshTokenFromDatabase == null)
                return BadRequest();

            if (refreshTokenFromDatabase.ExpiresUtc < DateTime.Now.ToUniversalTime())
                return Unauthorized();

            if (!await _accountService.CanSignInAsync(refreshTokenFromDatabase.User))
                return Unauthorized();

            //if (_accountService.SupportsUserLockout && await _accountService.IsLockedOutAsync(refreshTokenFromDatabase.User))
            //    return Unauthorized();

            var token = GenerateJwtToken(refreshTokenFromDatabase.User.Email, refreshTokenFromDatabase.User, out DateTime expires, true);

            var response = new TokenResponse
            {
                AccessToken = token,
                RefreshToken = refreshTokenFromDatabase.Token,
                FirstName = refreshTokenFromDatabase.User.FirstName,
                LastName = refreshTokenFromDatabase.User.LastName,
                TokenExpiration = expires
            };

            return Ok(response);
        }
1 голос
/ 21 октября 2019

Существует чрезвычайно полезная библиотека для работы с JWT внутри приложения Angular.

Вам следует попробовать. https://github.com/auth0/angular2-jwt

С этой библиотекой вам не нужно самостоятельно управлять токеном, вы можете просто настроить ее на отправку токена для каждого http-запроса, который вы делаете.

Вы даже можете запроситьтокен обновления в случае, если токен истек.

Все встроено в библиотеку. Проще и безопаснее, чем управлять токеном самостоятельно.

0 голосов
/ 21 октября 2019

Из этого примера вы можете сделать это следующим образом.

login(user: LoginModel): Observable<any> {
        return this.getTokens(user, 'password')
            .catch(res => Observable.throw(res.json()))
            .do(res => this.scheduleRefresh());
    }

private scheduleRefresh(): void {
    this.refreshSubscription$ = this.tokens$
        .first()
        // refresh every half the total expiration time
        .flatMap(tokens => Observable.interval(tokens.expires_in / 2 * 1000))
        .flatMap(() => this.refreshTokens())
        .subscribe();

Поэтому, когда мы войдем в систему, мы запустим scheduleRefresh для автоматического обновления токена в фоновом режиме

...