token解决前后端分离认证和跨域问题和JWT的使用

摘要:
=null&&!

二、使用token解决前端后端分离用户认证问题

2.1 用户提交帐号和密码到服务器的认证接口

  • login.html

  • doSubmit:function(){
        console.log("~~~~~~~~~~~~~doSubmit");
        axios.get("http://localhost:8080/user/login",{
            params:{
                username:this.username,
                password:this.password
            }
        }).then(function(res){
            if(res.data.code==0){
                var token =res.data.data;
                //在前端存储token
                document.cookie = "token="+token;
                //localStorage.setItem("token",token);
                //跳转到index.html
                location.href = "http://t.zoukankan.com/index.html";
            }else{
                //弹出提示框:提示登录失败
    }
        });
    }

    2.2 认证接口

    • --> 接受帐号和密码进行认证

    • --> 生成token(如果是随机token则需要在服务器进行存储,如果是按照特定的协议生成则无需存储)

    • --> 将生成的token响应给前端

  • UserController
    • @RequestMapping(value = "/login",method =RequestMethod.GET)
      @ApiOperation(value = "用户认证接口",notes = "调用此接口的注意事项")
      @ApiImplicitParams({
          @ApiImplicitParam(paramType = "query",name="username", required = true,dataType = "Book"),
          @ApiImplicitParam(paramType = "query",name="password",required = true,dataType = "String")
      })
      publicResultVO login(String username, String password, HttpServletRequest request) {
          try{
              User user  =userService.checkLogin(username, password);
              if (user!=null){
                  //登录成功
                  //request.getSession().setAttribute("user",user);
                  //b.生成token(自定义生成规则)
                  String token =TokenUtil.createToken(username);
                  //c.将token回传给前端
                  return new ResultVO(0,"success",token);
              }
          } catch(Exception e) {
              e.printStackTrace();
          }
          return new ResultVO(1,"fail");
      }
      public classTokenUtil {
      
          public staticString createToken(String username){
              String f = username.substring(0,1);
              String l = username.substring(username.length()-1);
              String str = l+f+username+l+f;
              String token = username+"."+Base64.encode(str.getBytes());
              returntoken;
          }
      
      }

2.3 前端获取并存储token(cookie,localstorage)

  • 在登录页面的回调函数中

  • if(res.data.code==0){
        var token =res.data.data;
        //在前端存储token
        document.cookie = "token="+token;
        //localStorage.setItem("token",token);
        //跳转到index.html
        location.href = "http://t.zoukankan.com/index.html";
    }else{
        //弹出提示框:提示登录失败
    }

2.4 当前端再次请求服务器接口时必须携带token

  • 当再次请求接口时,需要携带token

  • //【获取token】//1.从cookie获取
    var cks = document.cookie.split(",");
    for(var i=0; i<cks.length; i++){
        if(cks[i].split("=")[0] == "token"){
            this.token = cks[i].split("=")[1];
        }
    }
    
    //2.从localStorage获取
    this.token = localStorage.getItem("token");
    
    
    //【axios发送请求,header携带token】//1.设置axios的请求header中常驻token
    axios.defaults.headers.common["token"] = this.token;
    
    //2.在每次请求时设置token
    axios({
        url:"",
        method:"",
        params:{},
        data:{},
        headers:{
            token:this.token
        }
    }).then(res=>{
        //处理响应结果
    });

2.5 在服务器通过拦截器验证token

  • 创建自定义异常类处理token不合法异常

  • public class UnTokenException extendsException {
        publicUnTokenException(String message) {
            super(message);
        }
    }
  • 创建拦截器
  • @Component
    public class LoginInterceptor implementsHandlerInterceptor {
    
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throwsException {
            if("options".equalsIgnoreCase(request.getMethod())){
                return true;
            }else{
                String token = request.getHeader("token");
                System.out.println(token);
                if (token != null && !"".equals(token)) {
                    //验证token
                    String username = token.split("[.]")[0];
                    String rightToken =TokenUtil.createToken(username);
                    if(rightToken.equals(token)) {
                        return true;
                    } else{
                        //抛出自定义异常,通过全局异常处理返回给前端一个VO(包含“请先登录”提示信息)
                        throw new UnTokenException("非法token,请认证");
                    }
                } else{
                    throw new UnTokenException("请求参数不正确(缺少token)");
                }
            }
        }
    }
  • 配置拦截器

  • @Configuration
    public class AppConfig implementsWebMvcConfigurer {
    
        @Resource
        privateLoginInterceptor loginInterceptor;
    
        @Override
        public voidaddInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(loginInterceptor)
                    .addPathPatterns("/**")
                    .excludePathPatterns("/user/**");
        }
    
    }
  • 通过全局异常处理,处理token不合法问题
  • @ControllerAdvice
    @CrossOrigin
    public classUnTokenExceptionHanlder {
    
        @ExceptionHandler
        @ResponseBody
        publicResultVO exceptionHanlder(Exception e){
            return new ResultVO(1,e.getMessage());
        }
    
    }

三、服务器跨域设置

  • 跨域配置

  • @Configuration
    public classCrossConfig {
        @Bean
        publicWebMvcConfigurer getWebMvcConfigurer() {
            WebMvcConfigurer webMvcConfigurer = newWebMvcConfigurer() {
                @Override
                public voidaddCorsMappings(CorsRegistry registry) {
                    registry.addMapping("/**")
                            .allowedOrigins("*")
                            .allowedHeaders("*")
                            .allowedMethods("*")
                            .allowCredentials(false);
                }
            };
            returnwebMvcConfigurer;
        }
    
    }
    • 在控制器(接口)添加@CrossOrigin

    • 拦截放行预检

    • @Component
      public class LoginInterceptor implementsHandlerInterceptor {
      
          @Override
          public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throwsException {
              if("options".equalsIgnoreCase(request.getMethod())){
                  return true;
              }else{
                  String token = request.getHeader("token");
                  System.out.println(token);
                  if (token != null && !"".equals(token)) {
                      //验证token
                      String username = token.split("[.]")[0];
                      String rightToken =TokenUtil.createToken(username);
                      if(rightToken.equals(token)) {
                          return true;
                      } else{
                          //抛出自定义异常,通过全局异常处理返回给前端一个VO(包含“请先登录”提示信息)
                          throw new UnTokenException("非法token,请认证");
                      }
                  } else{
                      throw new UnTokenException("请求参数不正确(缺少token)");
                  }
              }
          }
      }

4.1在项目中导入JWT依赖

<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>3.8.3</version>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>

4.2 生成Token

String token =Jwts.builder()
    .setSubject(user.getUsername())     //设置用户信息
    .setId(user.getId()+"")             //设置用户ID
    .setIssuedAt(new Date())            //设置token的创建时间
    .setExpiration(new Date(System.currentTimeMillis()+60*1000))  //设置过期时间
    .signWith(SignatureAlgorithm.HS256,"qianfeng")  //加密方式及key
    .compact();

4.3 拦截器校验token

@Component
public class LoginInterceptor implementsHandlerInterceptor {

    @Override
    public booleanpreHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throwsUnTokenException, ExpiredJwtException,SignatureException {
        if("options".equalsIgnoreCase(request.getMethod())){
            return true;
        }else{
            String token = request.getHeader("token");
            System.out.println(token);
            if (token != null && !"".equals(token)) {
                //校验token
                JwtParser parser =Jwts.parser();
                parser.setSigningKey("qianfeng");

                //解析token,只要不抛出异常表示token正常
                Jws<Claims> claimsJws =parser.parseClaimsJws(token);
                //从token中获取信息
                Claims body =claimsJws.getBody();
                String subject =body.getSubject();
                return true;
            } else{
                throw  new UnTokenException("token为NULL");
            }
        }
    }
}

免责声明:文章转载自《token解决前后端分离认证和跨域问题和JWT的使用》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇(转)利用openfiler实现iSCSI将xml文件数据导入到sql中[原]下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

iOS开发 字符串

iOS开发之玩转字符串 (转)这是另一个收藏的超链接 来自SegmentFault 大神的精品 下面这是一些常用的方法和属性 记得不牢所以收藏下 //一、NSString /*----------------创建字符串的方法----------------*///1、创建常量字符串。NSString *astring = @"This is a Strin...

【Swift】UILabel的简单操作方法

@IBActionfuncbuttonClick_LabelCtrl(sender: AnyObject) { //定义CGRect来初始化UILable varframe: CGRect= CGRect(x: 50, y: 50, 200, height: 200) varlabel: UILabel= UILabel(frame: frame) //获...

java中String编码转换 UTF-8转GBK

1.GB2312等都可以用GBK代替.2.new String(row.getBytes("GB2312"), "UTF8") 这种写法是不对的, 中文仍然会乱码. 方案:解决GBK字符转UTF-8乱码问题: https://www.cnblogs.com/xijin-wu/p/5884822.html 彻底搞懂编码 GBK 和 UTF8:https:/...

tips

史上最全的Unity面试题(持续更新总结。。。。。。) 包含答案的Unity面试题 这个是我刚刚整理出的Unity面试题,为了帮助大家面试,同时帮助大家更好地复习Unity知识点,如果大家发现有什么错误,(包括错别字和知识点),或者发现哪里描述的不清晰,请在下面留言,我会重新更新,希望大家共同来帮助开发者 一:什么是协同程序? 在主线程运行的同时开启另...

2019面试宝典之.Net

  1、简述 private、 protected、 public、 internal 修饰符的访问权限。 private : 私有成员, 在类的内部才可以访问。 protected : 保护成员,该类内部和继承类中可以访问。 public : 公共成员,完全公开,没有访问限制。 internal: 当前程序集内可以访问。 2、ADO.NET中的五个主要...

(2)OLEDB数据库操作

1、首先要引入 System.Data.OracleClient.dll 2、引入命名空间using System.Data.OleDb; OleDb类https://msdn.microsoft.com/zh-cn/library/system.data.oledb(v=vs.110).aspx 一、连接数据库 连接字符串 string str = "...