参考: https://www.cnblogs.com/lyl6796910/p/6648891.html
https://www.cnblogs.com/lyl6796910/p/6648891.html
1, .net core使用jwt验证
首先创建一个类 JwtSeetings

 public  class JwtSeetings
    {
        /// <summary>
        /// 谁颁发的jwt
        /// </summary>
        public string Issuer { get; set; }

        /// <summary>
        /// 谁使用这个jwt
        /// </summary>
        public string Audience { get; set; }

        /// <summary>
        /// secret是保存在服务器端的,jwt的签发生成也是在服务器端的,secret就是用来进行jwt的签发和jwt的验证,
        /// 所以,它就是你服务端的私钥,在任何场景都不应该流露出去。一旦客户端得知这个secret, 那就意味着客户端是可以自我签发jwt了
        /// 通过jwt header中声明的加密方式进行加盐secret组合加密,然后就构成了jwt的第三部分
        /// </summary>
        public string SecretKey { get; set; }
    }

在配置文件appsettings.json中添加JwtSeetings

 "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "AllowedHosts": "*",
  "JwtSeetings": {
    "Issuer": "http://192.168.0.102:5000",
    "Audience": "http://localhost:8080",
    "SecretKey": "zhoudafu201807041123"
  }

然后在startup.cs中的ConfigureServices方法中注册jwt

   public void ConfigureServices(IServiceCollection services)
        {       
            services.Configure<JwtSeetings>(Configuration.GetSection("JwtSeetings"));
            var jwtSeetings = new JwtSeetings();
            //绑定jwtSeetings
            Configuration.Bind("JwtSeetings", jwtSeetings);
            services.AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;

            })
            .AddJwtBearer(options =>
            {
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidIssuer = jwtSeetings.Issuer,
                    ValidAudience = jwtSeetings.Audience,
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSeetings.SecretKey))
                };
            });
		//以上是注册jwt
            services.Configure<CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });
            //指定域名  允许任何来源的主机访问 builder.AllowAnyOrigin()
            services.AddCors(options =>
            {
                options.AddPolicy("allow_all", builder =>
                {
                    builder.WithOrigins(jwtSeetings.Audience) 
                    .AllowAnyMethod()
                    .AllowAnyHeader()
                    .AllowCredentials();//指定处理cookie
                });
            });


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

然后在Configure方法中添加

 app.UseStaticFiles();
 app.UseCookiePolicy();

然后在控制器中登陆的时候使用,新建 LoginController控制器,我这里有使用log4net日志,不用的可以去掉

public class LoginController : Controller
    {
        private JwtSeetings _jwtSeetings;
        private ILogger<LoginController> _logger;
        public LoginController(IOptions<JwtSeetings> option, ILogger<LoginController> logger)
        {
            _jwtSeetings = option.Value;
            _logger = logger;
        }
        public IActionResult Index()
        {
            return View();
        }

        [HttpPost]
        public IActionResult Login(string username,string password)
        {
            try
            {
                Logger.Info(JsonConvert.SerializeObject("进入登陆方法:username:"+username+";password:"+password));
                LgUser user = new LgUser();
                var claims = new Claim[]
                   {
                    new Claim(ClaimTypes.Name,username),
                    new Claim(ClaimTypes.Role,"admin")
                   };
                var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtSeetings.SecretKey));
                var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
                var token = new JwtSecurityToken(
                    _jwtSeetings.Issuer,
                    _jwtSeetings.Audience,
                    claims,
                    DateTime.Now,
                    DateTime.Now.AddMinutes(30),
                    creds
                    );
                return Ok(new { Code = 20000, token = new JwtSecurityTokenHandler().WriteToken(token) });
            }
            catch (Exception ex)
            {
                Logger.Info(JsonConvert.SerializeObject(ex.Message));
                throw;
            }
        }
    }

然后在其他需要验证的控制器上添加特性

 [Authorize]

就可以了,自己测试效果吧,再说一下vue里面的调用,如果是初识vue的需要注意以下axios post传参的坑,我这里是封装了一个request.js,需要用qs转换一下参数,不然用默认的mvc后台接受到的是null

import axios from 'axios'
import { Message, MessageBox } from 'element-ui'
import store from '../store'
import { getToken } from '@/utils/auth'
import qs from 'qs'

// 创建axios实例
const service = axios.create({
  baseURL: 'http://192.168.0.102:5000/', // api 的 base_url
  timeout: 50000 // 请求超时时间
})

// request拦截器
service.interceptors.request.use(
  config => {
    console.log(config.data);
    config.data =qs.stringify(config.data);
    config.headers = {
      'Content-Type':'application/x-www-form-urlencoded;charset=UTF-8'
    }
    if (store.getters.token) {
      config.headers['X-Token'] = getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
    }
    return config
  },
  error => {
    // Do something with request error
    console.log(error) // for debug
    Promise.reject(error)
  }
)

// response 拦截器
service.interceptors.response.use(
  response => {
    /**
     * code为非20000是抛错 可结合自己业务进行修改
     */
    const res = response.data
    if (res.code !== 20000) {
      Message({
        message: res.message,
        type: 'error',
        duration: 5 * 1000
      })

      // 50008:非法的token; 50012:其他客户端登录了;  50014:Token 过期了;
      if (res.code === 50008 || res.code === 50012 || res.code === 50014) {
        MessageBox.confirm(
          '你已被登出,可以取消继续留在该页面,或者重新登录',
          '确定登出',
          {
            confirmButtonText: '重新登录',
            cancelButtonText: '取消',
            type: 'warning'
          }
        ).then(() => {
          store.dispatch('FedLogOut').then(() => {
            location.reload() // 为了重新实例化vue-router对象 避免bug
          })
        })
      }
      return Promise.reject('error')
    } else {
      return response.data
    }
  },
  error => {
    console.log('err' + error) // for debug
    Message({
      message: error.message,
      type: 'error',
      duration: 5 * 1000
    })
    return Promise.reject(error)
  }
)

export default service

Logo

前往低代码交流专区

更多推荐