• 前后台分离使用token


    使用场景:前后端分离时(后台使用的是springboot,前端使用的是uniapp),当前台请求登录接口时,后台进行储存用户信息,并生成token,并返回给前端.前端请求其他接口都需要在头部带着token ,才能请求。下面来具体代码说明吧。(对你们有帮助的谢谢点赞收藏,错误的地方也谢谢评论提出,加以改善)

    第一步:在pom.xml 文件中引入jar包

         <!-- token包-->
            <dependency>
                <groupId>io.jsonwebtoken</groupId>
                <artifactId>jjwt</artifactId>
                <version>0.9.1</version>
            </dependency>

    第二步:使用工具类JwtUtils.java (这是生成token,和获取token的机制,直接复制可用)

    package com.example.changcai.smart_device.tool;
    import io.jsonwebtoken.Claims;
    import io.jsonwebtoken.JwtBuilder;
    import io.jsonwebtoken.Jwts;
    import io.jsonwebtoken.SignatureAlgorithm;
    import org.apache.tomcat.util.codec.binary.Base64;
    import javax.crypto.SecretKey;
    import javax.crypto.spec.SecretKeySpec;
    import javax.servlet.http.HttpServletRequest;
    import java.security.Key;
    import java.util.Date;
    import java.util.Map;
    
    /**
     * jwt
     */
    public class JwtUtils {
    
        /**
         * @param claims 自定义的 map
         * @param ttl    过期时间
         * @return
         */
        public static String createToken(Map<String, Object> claims, Long ttl) {
            Key key = generateKey();
            SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
            Long nowMillis = System.currentTimeMillis();
            JwtBuilder builder = Jwts.builder()
                    .setHeaderParam("typ", "JWT")
                    .setHeaderParam("alg", "HS256")
                    .setClaims(claims)
                    .signWith(signatureAlgorithm, key);
            if (ttl != null && ttl >= 0) {
                Long expMillis = nowMillis + ttl * 1000;
                Date exp = new Date(expMillis);
                builder.setExpiration(exp);
            }
            return builder.compact();
        }
    
        /**
         * @param claims 自定义的 map
         * @return
         */
        public static String createToken(Map<String, Object> claims) {
            return createToken(claims, null);
        }
    
        /**
         * @param jwt 创建的 jwt 字符串
         * @return
         */
        public static Claims parse(String jwt) {
    
            if (jwt == null) {
                return null;
            }
    
            try {
                return Jwts.parser()
                        .setSigningKey(generateKey())
                        .parseClaimsJws(jwt)
                        .getBody();
            } catch (Exception e) {
    
                return null;
            }
        }
    
        /**
         * @return
         */
        private static SecretKey generateKey() {
            String stringKey = "changcai";
            byte[] encodedKey = Base64.decodeBase64(stringKey);
            return new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
        }
    
        /**
         * @return
         */
        public static Integer getParseToken(HttpServletRequest request, String token, String key) {
            Claims parse = parse(token);
            if (parse == null) {
                return null;
            }
            return (Integer) parse.get(key);
        }
    
        public static Integer getParseToken(String token, String key) {
            Claims parse = parse(token);
            if (parse == null) {
                return null;
            }
            return (Integer) parse.get(key);
        }
    
        /*public static String getParseTokenStr(HttpServletRequest request, String token, String key) {
            Claims parse = parse(token);
            if (parse == null) {
                return null;
            }
            return (String) parse.get(key);
        }*/
    
        public static Long parseTokenStr(String token, String key) {
            Claims parse = parse(token);
            Object uid = parse.get(key);
            return Long.parseLong(uid.toString());
        }
    
        public static void main(String[] args) {
            System.out.println(generateKey());
        }
    
    }
    

    第三步:后台登录接口存储token,并返回给前端 该controller 继承一个BaseController

        @ApiOperation("用户登录接口Token")
        @RequestMapping(value = "wechatLoginToken",method = RequestMethod.POST)
        @ResponseBody
        public ResultInfo wechatLoginToken(@RequestBody @ApiParam("用户对象") Member member1){
            HashMap<String,Object> map=new HashMap();
            Member member=memberService.byUserName(member1.getUsername());
            if(null==member){
                return new ResultInfo(203,"用户不存在!",false);
            }else{
                if("1".equals(member.getIsEnable())){
                    return new ResultInfo(204,"用户已禁用!",false);
                }else if("1".equals(member.getIsDeleted())){
                    return new ResultInfo(204,"用户已删!",false);
                }else{
                    if(!member.getPassword().equals(MD5Util.md5(member1.getPassword()))){
                        return new ResultInfo(203,"用户密码不正确!",false);
                    }else{
                        //登录成功后
                        HashMap<String, Object> claims = new HashMap<>();
                        claims.put("id", member.getId());
                        //token过期时间24小时
                        String token = JwtUtils.createToken(claims, 864000L);
                        map.put("token",token);
                        map.put("member",member);
    
                        return new ResultInfo(200,"用户登录成功!",map);
                    }
                }
    
            }
        }

    第四步:BaseController(主要解析token )

    package com.example.changcai.smart_device.controller;
    
    
    import com.example.changcai.smart_device.entity.Member;
    import com.example.changcai.smart_device.service.MemberService;
    import com.example.changcai.smart_device.tool.JwtUtils;
    import com.github.pagehelper.util.StringUtil;
    import io.jsonwebtoken.Claims;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.stereotype.Component;
    import org.springframework.web.bind.annotation.ModelAttribute;
    import javax.annotation.Resource;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    @Slf4j
    @Component
    public class BaseController {
        @Resource
        protected HttpServletRequest request;
        @Resource
        protected HttpServletResponse response;
        @Resource
        private MemberService memberService;
        protected Member member;
        
        @ModelAttribute
        public Member getMember() {
            String token = request.getHeader("X-Token");
            if (StringUtil.isNotEmpty(token)) {
                System.out.println("token的值:"+token);
                Claims parse = JwtUtils.parse(token);
                Object obj = parse.get("id");
                member = memberService.getById(obj.toString());
                return member;
            }
            return null;
        }
    
    }

    测试登录后返回的值

    再写一个controller测试类,登录后,传token 获取member 对象

        @ApiOperation("通过Token获取用户")
        @RequestMapping(value = "byTokenGetMember",method = RequestMethod.POST)
        @ResponseBody
        public ResultInfo byTokenGetMember(){
         return new ResultInfo(200,"用户登录成功!",member);
        }

    测试效果如

    注意点1:前端请求其他接口时,都需要把token 带在头部,参数格式是:

    headers:{

    X-Token:前端登录成功后保存的token值

    }

    注意点2:如果项目使用到了swagger,请求接口heard头部想显示“X-Token”

    代码截图

    效果:

      

  • 相关阅读:
    用C++读写EXCEL文件的几种方式比较
    20个值得收藏的网页设计开放课件
    char* 应用, 去除字符串内多余空格, 用算法而非库函数
    东拉西扯:王建硕主义
    Lisp 的本质(The Nature of Lisp)
    web前端:html
    [原译]理解并实现原型模式实现ICloneable接口.理解深浅拷贝
    [原译]理解并实现装饰器模式
    3分钟理解Lambda表达式
    [原译]实现IEnumerable接口&理解yield关键字
  • 原文地址:https://www.cnblogs.com/chenlijing/p/16319982.html
Copyright © 2020-2023  润新知