1. 程式人生 > 其它 >前後端分離專案中的jwt令牌應用

前後端分離專案中的jwt令牌應用

做為前後端分離專案中,授權認證常用token令牌做為身份認證的方式,對於jwt令牌的獲取、驗證、解析以及儲存,分別示例如下:

1、JWT令牌生成及獲取

                    //寫Session或Cookies換成JWT


                    IList<Claim> claims = new List<Claim> {
                        new Claim(JwtClaimTypes.Id,admin.AdminId.ToString()),
                        new Claim(JwtClaimTypes.Name,loginDto.UserName),
                        
new Claim(JwtClaimTypes.Email,loginDto.UserName), new Claim(JwtClaimTypes.Role,string.Join(",", "")) }; //JWT金鑰 var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["JwtConfig:Bearer:SecurityKey"]));
//演算法 var cred = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); //過期時間 DateTime expires = DateTime.UtcNow.AddHours(10); //Payload負載 var token = new JwtSecurityToken( issuer: configuration[
"JwtConfig:Bearer:Issuer"], audience: configuration["JwtConfig:Bearer:Audience"], claims: claims, notBefore: DateTime.UtcNow, expires: expires, signingCredentials: cred ); var handler = new JwtSecurityTokenHandler(); //生成令牌 string jwt = handler.WriteToken(token);

2、JWT驗證部分

JWT在Startup中的配置,主要用來使用固定的配置金鑰對JWT的Token進行有效性驗證。

            //資料庫連線
            services.AddDbContext<SmsDBContext>(action => {
                action.UseSqlServer(Configuration.GetConnectionString("Default"));
            });

            services.AddCors(option =>
            {
                option.AddDefaultPolicy(policy =>
                {
                    //對應客戶端withCredentials,需要設定具體允許的域名
                    policy.WithOrigins("http://web.a.com:88").AllowCredentials();
                    policy.AllowAnyMethod();
                    policy.AllowAnyHeader();
                });
            });

            services.AddAuthentication(option => {
                option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                option.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            }).AddJwtBearer(
                option => {
                    option.TokenValidationParameters = new TokenValidationParameters
                    {
                        //是否驗證發行人
                        ValidateIssuer = true,
                        ValidIssuer = Configuration["Authentication:JwtBearer:Issuer"],//發行人

                        //是否驗證受眾人
                        ValidateAudience = true,
                        ValidAudience = Configuration["Authentication:JwtBearer:Audience"],//受眾人

                        //是否驗證金鑰
                        ValidateIssuerSigningKey = true,
                        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Authentication:JwtBearer:SecurityKey"])),

                        ValidateLifetime = true, //驗證生命週期

                        RequireExpirationTime = true, //過期時間

                        ClockSkew = TimeSpan.Zero   //平滑過期偏移時間
                    };
                }
            );

另外,還需要配置相應的認證中介軟體和授權中介軟體

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseSwagger();
                string ApiName = "Rbac.Core";
                app.UseSwaggerUI(c =>
                {
                    c.SwaggerEndpoint("/swagger/V1/swagger.json", $"{ApiName} V1");
                    c.SwaggerEndpoint("/swagger/gp/swagger.json", "登入模組");
                    c.SwaggerEndpoint("/swagger/mom/swagger.json", "業務模組");
                    c.SwaggerEndpoint("/swagger/dm/swagger.json", "其他模組");

                    //路徑配置,設定為空,表示直接在根域名(localhost:8001)訪問該檔案,注意localhost:8001/swagger是訪問不到的,去launchSettings.json把launchUrl去掉,如果你想換一個路徑,直接寫名字即可,比如直接寫c.RoutePrefix = "doc";
                    c.RoutePrefix = "";
                });
            }

            //app.UseHttpsRedirection();

            //靜態檔案中介軟體
            app.UseStaticFiles();

            //路由中介軟體
            app.UseRouting();

            //跨域
            app.UseCors();

            //認證中介軟體
            app.UseAuthentication();

            //授權中介軟體
            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }

經過上面配置,可以完成JWT令牌的生成及校驗。

3、前端Axios的令牌儲存及請求授權介面

前端接收到Api介面返回的token令牌後,應該把token儲存起來,儲存的位置可以是localStorage或sessionStorage,當訪問授權介面時,從localStorage或sessionStorage中取出令牌,通過HTTP請求頭進行訪問。

import router from '../router'
import axios from 'axios'
let baseUrl = "http://localhost:5000/api";

axios.defaults.baseURL = baseUrl;
axios.defaults.headers.common['Authorization'] = `bearer ${localStorage.getItem('token')}`;

// 新增響應攔截器
axios.interceptors.response.use(function (response) {
    // 對響應資料做點什麼
    return response;
  }, function (error) {
    router.push("/");
    return Promise.reject(error);
  });

export default {
    baseUrl,
    axios
}