其他分享
首页 > 其他分享> > 前后台分离使用token

前后台分离使用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”

代码截图

 

 

 

效果:

 

 

  

 

标签:前后,return,String,分离,parse,token,import,public
来源: https://www.cnblogs.com/chenlijing/p/16319982.html