ASP.NETコア2.2 :. 26個のアプリケーションJWTのユーザ認証とトークンリフレッシュ

出典:https://www.cnblogs.com/FlyLolo/p/ASPNETCore2_26.html

 

この記事では、どのようにユーザー認証と(JWTのASP.NET Coreアプリケーションにおけるトークンリフレッシュプログラムの実用的な例を挙げて紹介しますASP.NETコアシリーズカタログ

まず、JWTは何ですか?

オープンな標準(RFC 7519)に基づいて、JWT(JSONウェブトークン)は、ステートレスな分散認証方式は、主に安全なネットワーク環境中に文を配信するために使用されています。これは、JSONに基づいており、それは、.NET、JAVA、JavaScriptが,, PHPと他の言語として、JSONのように使用することができます。
なぜJWTを使うのか?
従来のWebアプリケーションでは、一般的に、認証のためにクッキー+セッションを使用します。しかし、アプリケーション、アプレットやその他のアプリケーションが増え、ステートレスのサーバー通常、RESTfulなタイプ、それらに対応するAPIのために、この認証方法を使用することは非常に便利ではありません。ステートレス分散認証方式は、まさにこの需要に沿ったものであることをJWT。

二つは、JWTの構成は次のとおりです。

JWTは、どのように見えるかですか?それは次のような文字列である:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjAwMiIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL25hbWUiOiLmnY7lm5siLCJuYmYiOjE1NjU5MjMxMjIsImV4cCI6MTU2NTkyMzI0MiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo1NDIxNCIsImF1ZCI6Imh0dHA6Ly9sb2NhbGhvc3Q6NTQyMTUifQ.Mrta7nftmfXeo_igBVd4rl2keMmm0rg0WkqRXoVAeik
「」これは、2つの文字列を形成するために一緒に接続された3つのセグメントの『歪み』から構成されています。公式サイトのhttps://jwt.io/は、その認証を提供します

 

 


ヘッダ、ペイロードと署名図の右側にある三つの部分に対応し、その3つの文字列。

ヘッダ:

ヘッダ:
{ 
"ALG": "HS256"、
"標準": "JWT" 
}

HS256、トークン型JWTとして識別暗号化は、本実施形態の第1列はJSONはBase64Urlを符号化することによって形成されています

ペイロード

ペイロードは多くの文(特許請求の範囲)が含ま情報記憶部用JWTあります。
あなたがペイロードに追加複数の宣言をカスタマイズすることができ、システムはまた、いくつかのデフォルトの型を提供
発行者:ISS(発行者)
EXP(有効期限):有効期限の
サブ(件名):テーマ
AUD(聴衆):オーディエンス
NBF(前ではなくを):効果的な時間
の時間の問題:(発行時)IAT
JTI(JWT ID):いいえ。

コードBase64Urlによって生成された第2の列のこの部分。

署名

署名の検証は、トークンのためです。このように、その値式:(「」base64UrlEncode(ヘッダ)+ + base64UrlEncode(ペイロード)、秘密)署名= HMACSHA256、それは新しい文字列によって生成され、あるは2前後で​​暗号化されています文字列。

そのため、最初の二つの文字列を通じて同じ文字列を得るために、同じ暗号化キーを持っている人だけが、この方法は、トークンの信頼性を確保します。

第三に、認証プロセス

おそらくプロセスはこれです:

  1. 認証サーバー:ユーザー認証とトークンの発行のログイン。
  2. アプリケーションサーバー:ビジネス・データ・インタフェース。保護されたAPI。
  3. クライアント:一般APP、小さな手続き。

認定プロセス:

  1.  ユーザートークンを取得するには、ロギング、認証サーバによって最初に。
  2. APIサーバーへのアプリケーションアクセスすると、取得しトークンをリクエストのヘッダーに配置されます。
  3. アプリケーションサーバは、トークン、対応するポストによって返される結果を検証します。

説明:これは、プログラムの一例であり、実際のプロジェクトは変更になる場合があります。

  1. 小規模なプロジェクトでは、それが一緒にサービスやアプリケーションサービスを認定することができます。私たちはより良い2間の認証プロセスを理解できるように、この例では、別々の方法によって達成されます。
  2. より複雑なプロジェクトでは、複数のアプリケーションサービスがあるかもしれない、ユーザーはトークンを取得する複数の分散サービスで認証され、これは、JWTの利点の一つであることができます。

 

ここJWTの多くの記事があまりにも多くを導入していません。それはのASP.NETコアに適用する方法で実用的な外観の一例を以下によります。

第四に、応用例

1上図:三つの部分のクライアントに関わる「JWT認証プロセス」、認証サーバ、アプリケーションサーバ、これらの三つの部分の以下のシミュレーションを例に挙げます:

  1. 認証サーバー:FlyLolo.JWT.Server呼ばWEBAPIソリューションを作成します。
  2. アプリケーションサーバー:FlyLolo.JWT.API呼ばWEBAPIソリューションを作成します。
  3. クライアント:フィドラーは、テストを行うための要求でここに送ら。

認証サービス

まず、新しいASP.NETコアソリューションのWEBAPIソリューションを作成 

FlyLolo.JWT.Serverという名前を付けます。

最初の発行のための新しいログイン名とトークンTokenControllerを作成します。

コードをコピー
[ルート( "API / [コントローラー]")] 
publicクラスTokenController:コントローラ
{ 
    プライベートITokenHelper tokenHelper = NULL; 
    公共TokenController(ITokenHelper _tokenHelper)
    { 
        tokenHelper = _tokenHelper。
    } 
    [HTTPGET] 
    パブリックIActionResult取得(文字列コード、ストリングPWD)
    { 
        ユーザーユーザー= TemporaryData.GetUser(コード)。
        IF(ヌル=ユーザ&& user.Password.Equals(PWD)!)
        { 
            リターンOK(tokenHelper.CreateToken(ユーザ))。
        } 
        )(BadRequestを返します。
    } 
}
コードをコピー

 これは、名前が検証した後、認証のために提出されたユーザ名とパスワードを受信するためのアクションを取得しており、CreateToken生成トークンTokenHelper呼び出す方法が返されます。

ここでは、ユーザーにして二つのクラスTokenHelper関連。

ユーザー関連:

コードをコピー
パブリッククラスユーザー
{ 
    公共の文字列コード{取得します。セットする; } 
    パブリック文字列名前{得ます。セットする; } 
    パブリック文字列のパスワード{取得します。セットする; } 
}
コードをコピー

唯一のデモ以来、ユーザークラスはわずか3つの以上のフィールドが含まれています。ユーザーデータは、アナログクラスTemporaryDataで行われます

コードをコピー
    /// <まとめ> 
    ///ダミーデータ、ユーザは、データベースまたはアナログキャッシュから読み出される
    /// </要約> 
    パブリック静的クラスTemporaryData 
    { 
        プライベート静的リスト<ユーザー>ユーザーの(新しい新しい= <ユーザー>のリスト){新しい新規ユーザー{コード= "001"、 NAME = " ジョー・スミス"、パスワード= "111111"} 、新しいユーザー{コード= "002"、NAME = " ジョン・ドウ"、パスワード= "222222"}}; 

        公共静的GETUSERユーザ(文字コード)
        { 
            戻りUsers.FirstOrDefault(M => m.Code.Equals(コード)); 
        } 
    }
コードをコピー

これが唯一のアナログデータであり、実際のプロジェクトでは、データベース、またはキャッシュから読まれるべきです。

TokenHelper:

コードをコピー
パブリッククラスTokenHelper:ITokenHelper 
    { 
        プライベートIOptions <JWTConfig> _options。
        公共TokenHelper(IOptions <JWTConfig>オプション)
        { 
            _options =オプション。
        } 

        パブリックトークンCreateToken(ユーザユーザ)
        { 
            請求[]クレーム= {新しい項(ClaimTypes.NameIdentifier、user.Code)、新たな請求項(ClaimTypes.Name、user.Name)}。

            CreateToken(クレーム)を返します。
        } 
        プライベートトークンCreateToken(請求項[]の特許請求の範囲)
        { 
            VAR今= DateTime.Now; varは= now.Add(TimeSpan.FromMinutes(_options.Value.AccessTokenExpiresMinutes))を満了します。
            新しいJwtSecurityToken(=トークンVAR
                発行者:_options.Value.Issuer、 
                観客:_options.Value.Audience、
                請求:請求、
                notBeforeの:今、
                期限が切れる:満了し、
                signingCredentials:新しいSigningCredentials(新SymmetricSecurityKey(Encoding.UTF8.GetBytes(_options.Value.IssuerSigningKey))、 SecurityAlgorithms.HmacSha256)); 
            戻り新しいトークン{。TokenContent =新しいJwtSecurityTokenHandler()WriteToken(トークン)、有効期限=満了し}。
        } 
    }
コードをコピー

    CreateTokenメソッドによって作成されたトークン、ここではいくつかの重要なパラメータは、次のとおりです。

  1. トークンの発行者の発行者
  2. 観客トークンの受信者
  3. 有効期限が満了します
  4. IssuerSigningKey署名鍵

次のようにコードを対応するトークンです。

コードをコピー
    パブリッククラストークン
    { 
        公共の文字列TokenContent {取得します。セットする; } 

        公共の日時が有効期限{GET。セットする; } 
    }
コードをコピー

これは、トークンはTokenHelper CreateToken方法でクライアントに返さ生成します。今まで、一見すべての作業が完了しました。ない場合、我々はまだスタートアップファイルにいくつかの設定を行う必要があります。

コードをコピー
パブリッククラススタートアップ
{ 
// ......此处省略部分代码
ます。public void ConfigureServices(IServiceCollectionサービス) {
//读取配置信息 services.AddSingleton <ITokenHelper、TokenHelper>(); services.Configure <JWTConfig>(Configuration.GetSection( "JWT")); //启用JWT services.AddAuthentication(オプション=> { Options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; Options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; })。 AddJwtBearer(); services.AddMvc()SetCompatibilityVersion(CompatibilityVersion.Version_2_2)。 } 無効に設定公開(APP IApplicationBuilder、IHostingEnvironment ENV) { IF(env.IsDevelopment()) { app.UseDeveloperExceptionPage(); }
//認証中間イネーブル app.UseAuthenticationを(); app.UseMvc(); } }
コードをコピー

 これは、認証情報に設定情報を使用して、次のようにappsettings.json設定があります:

コードをコピー
  "JWT":{ 
    "発行者": "FlyLolo"、
    "観客": "TestAudience"、
    "IssuerSigningKey": "FlyLolo1234567890"、
    "AccessTokenExpiresMinutes": "30" 
  }
コードをコピー

 

プロジェクトを実行し、道のAPI /トークンコード= 002&PWD = 222222でFidderを取得するためのアクセス、次のような結果が返さ?:

{"tokenContent":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8
yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjAwMiIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL
3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL25hbWUiOiLmnY7lm5siLCJuYmYiOjE1NjY3OTg0NzUsImV4cCI6MTU2NjgwMDI
3NSwiaXNzIjoiRmx5TG9sbyIsImF1ZCI6IlRlc3RBdWRpZW5jZSJ9.BVf3gOuW1E9RToqKy8XXp8uIvZKL-lBA-q9fB9QTEZ4",
"expires":"2019-08-26T21:17:55.1183172+08:00"}

 

 客户端登录成功并成功返回了一个Token,认证服务创建完成

应用服务

新建一个WebApi的解决方案,名为FlyLolo.JWT.API。

添加BookController用作业务API。

コードをコピー
[Route("api/[controller]")]
[Authorize]
public class BookController : Controller
{
    // GET: api/<controller>
    [HttpGet]
    [AllowAnonymous]
    public IEnumerable<string> Get()
    {
        return new string[] { "ASP", "C#" };
    }

    // POST api/<controller>
    [HttpPost]
    public JsonResult Post()
    {
        return new JsonResult("Create  Book ...");
    }
}
コードをコピー

 对此Controller添加了[Authorize]标识,表示此Controller的Action被访问时需要进行认证,而它的名为Get的Action被标识了[AllowAnonymous],表示此Action的访问可以跳过认证。

在Startup文件中配置认证:

コードをコピー
public class Startup
{
// 省略部分代码
    public void ConfigureServices(IServiceCollection services)
    {
        #region 读取配置
        JWTConfig config = new JWTConfig();
        Configuration.GetSection("JWT").Bind(config);
        #endregion

        #region 启用JWT认证
        services.AddAuthentication(options =>
        {
            options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
        }).
        AddJwtBearer(options =>
        {
            options.TokenValidationParameters = new TokenValidationParameters
            {
                ValidIssuer = config.Issuer,
                ValidAudience = config.Audience,
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(config.IssuerSigningKey)),
                ClockSkew = TimeSpan.FromMinutes(1)
            };
        });
        #endregion

        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        app.UseAuthentication();
        app.UseMvc();
    }
}
コードをコピー

 这里同样用到了配置:

コードをコピー
    public class JWTConfig
    {
        public string Issuer { get; set; }
        public string Audience { get; set; }
        public string IssuerSigningKey { get; set; }
        public int AccessTokenExpiresMinutes { get; set; }
    }
コードをコピー

 appsettings.json:

コードをコピー
  "JWT": {
    "Issuer": "FlyLolo",
    "Audience": "TestAudience",
    "IssuerSigningKey": "FlyLolo1234567890",
    "AccessTokenExpiresMinutes": "30"
  }
コードをコピー

 关于JWT认证,这里通过options.TokenValidationParameters对认证信息做了设置,ValidIssuer、ValidAudience、IssuerSigningKey这三个参数用于验证Token生成的时候填写的Issuer、Audience、IssuerSigningKey,所以值要和生成Token时的设置一致。

ClockSkew默认值为5分钟,它是一个缓冲期,例如Token设置有效期为30分钟,到了30分钟的时候是不会过期的,会有这么个缓冲时间,也就是35分钟才会过期。为了方便测试(不想等太长时间),这里我设置了1分钟。

TokenValidationParameters还有一些其他参数,在它的构造方法中已经做了默认设置,代码如下:

コードをコピー
public TokenValidationParameters()
{
    RequireExpirationTime = true;  
    RequireSignedTokens = true;    
    SaveSigninToken = false;
    ValidateActor = false;
    ValidateAudience = true;  //是否验证接受者
    ValidateIssuer = true;   //是否验证发布者
    ValidateIssuerSigningKey = false;  //是否验证秘钥
    ValidateLifetime = true; //是否验证过期时间
    ValidateTokenReplay = false;
 }
コードをコピー

 访问api/book,正常返回了结果

["ASP","C#"]

 通过POST方式访问,返回401错误。

这就需要使用获取到的Toke了,如下图方式再次访问

添加了“Authorization: bearer Token内容”这样的Header,可以正常访问了。

至此,简单的JWT认证示例就完成了,代码地址https://github.com/FlyLolo/JWT.Demo/releases/tag/1.0

这里可能会有个疑问,例如:

   1.Token被盗了怎么办?

    答: 在启用Https的情况下,Token被放在Header中还是比较安全的。另外Token的有效期不要设置过长。例如可以设置为1小时(微信公众号的网页开发的Token有效期为2小时)。

   2. Token到期了如何处理?

   答:理论上Token过期应该是跳到登录界面,但这样太不友好了。可以在后台根据Token的过期时间定期去请求新的Token。下一节来演示一下Token的刷新方案。

五、Token的刷新

   为了使客户端能够获取到新的Token,对上文的例子进行改造,大概思路如下:

  1. 用户登录成功的时候,一次性给他两个Token,分别为AccessToken和RefreshToken,AccessToken用于正常请求,也就是上例中原有的Token,RefreshToken作为刷新AccessToken的凭证。
  2. AccessToken的有效期较短,例如一小时,短一点安全一些。RefreshToken有效期可以设置长一些,例如一天、一周等。
  3. 当AccessToken即将过期的时候,例如提前5分钟,客户端利用RefreshToken请求指定的API获取新的AccessToken并更新本地存储中的AccessToken。

所以只需要修改FlyLolo.JWT.Server即可。

首先修改Token的返回方案,新增一个Model

    public class ComplexToken
    {
        public Token AccessToken { get; set; }
        public Token RefreshToken { get; set; }
    }

包含AccessToken和RefreshToken,用于用户登录成功后的Token结果返回。

修改 appsettings.json,添加两个配置项:

    "RefreshTokenAudience": "RefreshTokenAudience", 
    "RefreshTokenExpiresMinutes": "10080" //60*24*7

 

RefreshTokenExpiresMinutes用于设置RefreshToken的过期时间,这里设置了7天。RefreshTokenAudience用于设置RefreshToken的接受者,与原Audience值不一致,作用是使RefreshToken不能用于访问应用服务的业务API,而AccessToken不能用于刷新Token。

修改TokenHelper:

コードをコピー
    public enum TokenType
    {
        AccessToken = 1,
        RefreshToken = 2
    }
    public class TokenHelper : ITokenHelper
    {
        private IOptions<JWTConfig> _options;
        public TokenHelper(IOptions<JWTConfig> options)
        {
            _options = options;
        }

        public Token CreateAccessToken(User user)
        {
            Claim[] claims = new Claim[] { new Claim(ClaimTypes.NameIdentifier, user.Code), new Claim(ClaimTypes.Name, user.Name) };

            return CreateToken(claims, TokenType.AccessToken);
        }

        public ComplexToken CreateToken(User user)
        {
            Claim[] claims = new Claim[] { new Claim(ClaimTypes.NameIdentifier, user.Code), new Claim(ClaimTypes.Name, user.Name)
                //下面两个Claim用于测试在Token中存储用户的角色信息,对应测试在FlyLolo.JWT.API的两个测试Controller的Put方法,若用不到可删除
                , new Claim(ClaimTypes.Role, "TestPutBookRole"), new Claim(ClaimTypes.Role, "TestPutStudentRole")
            };

            return CreateToken(claims);
        }

        public ComplexToken CreateToken(Claim[] claims)
        {
            return new ComplexToken { AccessToken = CreateToken(claims, TokenType.AccessToken), RefreshToken = CreateToken(claims, TokenType.RefreshToken) };
        }

        /// <summary>
        /// 用于创建AccessToken和RefreshToken。
        /// 这里AccessToken和RefreshToken只是过期时间不同,【实际项目】中二者的claims内容可能会不同。
        /// 因为RefreshToken只是用于刷新AccessToken,其内容可以简单一些。
        /// 而AccessToken可能会附加一些其他的Claim。
        /// </summary>
        /// <param name="claims"></param>
        /// <param name="tokenType"></param>
        /// <returns></returns>
        private Token CreateToken(Claim[] claims, TokenType tokenType)
        {
            var now = DateTime.Now;
            var expires = now.Add(TimeSpan.FromMinutes(tokenType.Equals(TokenType.AccessToken) ? _options.Value.AccessTokenExpiresMinutes : _options.Value.RefreshTokenExpiresMinutes));//设置不同的过期时间
            var token = new JwtSecurityToken(
                issuer: _options.Value.Issuer,
                audience: tokenType.Equals(TokenType.AccessToken) ? _options.Value.Audience : _options.Value.RefreshTokenAudience,//设置不同的接受者
                claims: claims,
                notBefore: now,
                expires: expires,
                signingCredentials: new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_options.Value.IssuerSigningKey)), SecurityAlgorithms.HmacSha256));
            return new Token { TokenContent = new JwtSecurityTokenHandler().WriteToken(token), Expires = expires };
        }

        public Token RefreshToken(ClaimsPrincipal claimsPrincipal)
        {
            var code = claimsPrincipal.Claims.FirstOrDefault(m => m.Type.Equals(ClaimTypes.NameIdentifier));
            if (null != code )
            {
                return CreateAccessToken(TemporaryData.GetUser(code.Value.ToString()));
            }
            else
            {
                return null;
            }
        }
    }
コードをコピー

 

在登录后,生成两个Token返回给客户端。在TokenHelper添加了一个RefreshToken方法,用于生成新的AccessToken。对应在TokenController中添加一个名为Post的Action,用于调用这个RefreshToken方法刷新Token

コードをコピー
[HttpPost]
[Authorize]
public IActionResult Post()
{
    return Ok(tokenHelper.RefreshToken(Request.HttpContext.User));
}
コードをコピー

这个方法添加了[Authorize]标识,说明调用它需要RefreshToken认证通过。既然启用了认证,那么在Startup文件中需要像上例的业务API一样做JWT的认证配置。

コードをコピー
        public void ConfigureServices(IServiceCollection services)
        {
            #region 读取配置信息
            services.AddSingleton<ITokenHelper, TokenHelper>();
            services.Configure<JWTConfig>(Configuration.GetSection("JWT"));
            JWTConfig config = new JWTConfig();
            Configuration.GetSection("JWT").Bind(config);
            #endregion

            #region 启用JWT
            services.AddAuthentication(Options =>
            {
                Options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                Options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            }).
             AddJwtBearer(options =>
             {
                 options.TokenValidationParameters = new TokenValidationParameters
                 {
                     ValidIssuer = config.Issuer,
                     ValidAudience = config.RefreshTokenAudience,
                     IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(config.IssuerSigningKey))
                 };
             });
            #endregion

            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
        }
コードをコピー

 

 注意这里的ValidAudience被赋值为config.RefreshTokenAudience,和FlyLolo.JWT.API中的不一致,用于防止AccessToken和RefreshToken的混用。

再次访问/api/token?code=002&pwd=222222,会返回两个Token:

コードをコピー
{"accessToken":{"tokenContent":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8y
MDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjAwMiIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUva
WRlbnRpdHkvY2xhaW1zL25hbWUiOiLmnY7lm5siLCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW
1zL3JvbGUiOlsiVGVzdFB1dEJvb2tSb2xlIiwiVGVzdFB1dFN0dWRlbnRSb2xlIl0sIm5iZiI6MTU2NjgwNjQ3OSwiZXhwIjoxNTY2ODA4Mjc5LCJ
pc3MiOiJGbHlMb2xvIiwiYXVkIjoiVGVzdEF1ZGllbmNlIn0.wlMorS1V0xP0Fb2MDX7jI7zsgZbb2Do3u78BAkIIwGg",
"expires":"2019-08-26T22:31:19.5312172+08:00"},

"refreshToken":{"tokenContent":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8y
MDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjAwMiIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUva
WRlbnRpdHkvY2xhaW1zL25hbWUiOiLmnY7lm5siLCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW
1zL3JvbGUiOlsiVGVzdFB1dEJvb2tSb2xlIiwiVGVzdFB1dFN0dWRlbnRSb2xlIl0sIm5iZiI6MTU2NjgwNjQ3OSwiZXhwIjoxNTY3NDExMjc5LCJ
pc3MiOiJGbHlMb2xvIiwiYXVkIjoiUmVmcmVzaFRva2VuQXVkaWVuY2UifQ.3EDi6cQBqa39-ywq2EjFGiM8W2KY5l9QAOWaIDi8FnI",
"expires":"2019-09-02T22:01:19.6143038+08:00"}}
コードをコピー

 

 可以使用RefreshToken去请求新的AccessToken

 

测试用AccessToken可以正常访问FlyLolo.JWT.API,用RefreshToken则不可以。

至此,Token的刷新功能改造完成。代码地址:https://github.com/FlyLolo/JWT.Demo/releases/tag/1.1

疑问:RefreshToken有效期那么长,被盗了怎么办,和直接将AccessToken的有效期延长有什么区别?

考えて:. 1 RefreshToken要求の大半で使用されているようAccessTokenません。2.漏れの可能性をおそらくもっとあることを、対応するサービスが(ある)よりAPIのように適用し、そう大きくなります。

おすすめ

転載: www.cnblogs.com/frank0812/p/11854572.html