Jwt登录退出

1.登录获取用户信息并写入token

@Override
    public CommonResult loginV2(RcSysUserEntity byAccount) {
        log.info("********************");
        log.info("******************** account-V2:{}",byAccount.getAccount());
        log.info("********************");
        CommonResult userInfoV2 = getUserInfoV2(byAccount);
        return userInfoV2;
    }
    //todo
    public CommonResult getUserInfoV2(RcSysUserEntity byAccount){
        List<TMenu> menus= new ArrayList<>();
        String tokenResult="";
        Map<String, Object> result = new HashMap<>();
        try {
            //获取权限信息
            Optional<TRole> tRoleopt=tRoleRepository.findById(Integer.valueOf(byAccount.getRoleId()));
            if(tRoleopt.isPresent()){
                TRole role = tRoleopt.get();
                List<TMenu> tMenus = tRoleService.querySysMenus(role.getMenuIds());
                menus = tRoleService.buildMenuTreeSelect(tMenus);
            }
            if(null!=byAccount){
                JwtPayLoad jwtPayLoad = new JwtPayLoad();
                jwtPayLoad.setId(byAccount.getId());
//                jwtPayLoad.setToken(byAccount.getToken());
                jwtPayLoad.setAccount(byAccount.getAccount());
                jwtPayLoad.setRealname(byAccount.getRealname());
                jwtPayLoad.setRoleId(byAccount.getRoleId());
                jwtPayLoad.setCtime(byAccount.getCtime());
                jwtPayLoad.setCuser(byAccount.getCuser());
                jwtPayLoad.setTel(byAccount.getTel());
                jwtPayLoad.setEmail(byAccount.getEmail());
                tokenResult = JwtTokenUtil.createToken(jwtPayLoad);

                result.put("token", tokenResult);
                result.put("permission", menus);
                result.put("userInfo", byAccount);
                //更新登录token
                byAccount.setToken(tokenResult);
                rcSysUserRepository.save(byAccount);
                //写入登录日志
                AsyncManager.me().execute(AsyncFactory.recordLogininfor(byAccount.getAccount(), byAccount.getAccount(), String.valueOf(byAccount.getId()), String.valueOf(byAccount.getId()), "", Constants.LOGIN_SUCCESS, "登录成功"));
                return CommonResult.success(result);
            }
        } catch (Exception e) {
            logger.info(e.getMessage());
        }
        return CommonResult.failed("认证失败,用户名或密码错误");
    }

2.token验证获取用户信息

/**
	 * token验证获取用户信息
	 * @param token
	 * @return
	 */
	@ApiOperation(value = "token验证获取用户信息",httpMethod = "POST")
	@RequestMapping(value = "tokenAuth")
	@ResponseBody
	public CommonResult tokenAuth(String token) {
		RcSysUserEntity userInfo = null;
		try {
			logger.debug("token验证获取用户信息...");
			RcSysUserEntity byToken = rcSysUserRepository.findByToken(token);
			if (null==byToken) return CommonResult.failed("token验证获取用户信息失效!");
			JwtPayLoad jwtPayLoad = JwtTokenUtil.getJwtPayLoad(token);
			CommonResult tokenUser = loginService.getTokenUserV2(jwtPayLoad);
			logger.debug("userInfo:{}",JSONObject.toJSONString(tokenUser.getData()));
			logger.debug("token验证获取用户信息 success !");
			return tokenUser;
		} catch (Exception e) {
			logger.debug("token验证获取用户信息 error !");
			e.printStackTrace();
		}
		Map<String, Object> resultMap=new HashMap<>();
		resultMap.put("userInfo",userInfo);
		logger.debug("resultMap:{}",JSONObject.toJSONString(resultMap));
		return CommonResult.success(resultMap);
	}
public CommonResult getTokenUserV2(JwtPayLoad jwtPayLoad) {
        Long id=jwtPayLoad.getId();
        Optional<RcSysUserEntity> byAccountOpt = rcSysUserRepository.findById(id);
        if (byAccountOpt.isPresent()) {
            RcSysUserEntity byAccount = byAccountOpt.get();
            //移除加密信息
            byAccount.setSalt("");byAccount.setPassword("");
            Optional<TRole> tRoleopt=tRoleRepository.findById(Integer.valueOf(byAccount.getRoleId()));
            if(tRoleopt.isPresent()){
                TRole role = tRoleopt.get();
                List<TMenu> tMenus = tRoleService.querySysMenus(role.getMenuIds());
                List<TMenu> menus = tRoleService.buildMenuTreeSelect(tMenus);
                byAccount.setMenus(menus);
                return CommonResult.success(byAccount);
            }
        }
        return CommonResult.failed("token验证获取用户信息失败!");
    }



@Override
    public List<TMenu> querySysMenus(String menu) {
        RowMapper<TMenu> rowMapper=new BeanPropertyRowMapper<>(TMenu.class);
        String query=" select * from t_sys_menu where 1=1 ";
        if (!menu.equals("-1")) {//-1为查全部
            query+=" and  find_in_set(id,'"+menu+"')  ";
        }
        List<TMenu> list = jdbcTemplate.query(query,rowMapper);
        return list;
    }


/**
     * 构建前端所需要下拉树结构
     *
     * @param menus 菜单列表
     * @return 下拉树结构列表
     */
    @Override
    public List<TMenu> buildMenuTreeSelect(List<TMenu> menus)
    {
        //转换为前端data格式
        List<TMenu> topNodes=menus.stream().filter(item->item.getParentId()==0).collect(Collectors.toList());
        List<TMenu> nodes=new ArrayList<>();
        for(TMenu item : topNodes){
            TMenu combotreeVo = new TMenu();
            combotreeVo.setId(item.getId());
            combotreeVo.setMenuName(item.getMenuName());
            combotreeVo.setParentId(item.getParentId());
            combotreeVo.setMenuUrl(item.getMenuUrl());
            fillSubNode(combotreeVo,menus);
            if(combotreeVo.getChildren()!=null&&combotreeVo.getChildren().size()>0){
                combotreeVo.setStatus(0);
            }else{
                combotreeVo.setStatus(1);
            }
            nodes.add(combotreeVo);
        }
        return nodes;
    }


    /**
     * 转换
     * @param pnode
     * @param all
     */
    public void fillSubNode(TMenu pnode, List<TMenu> all) {
        List<TMenu> subNodes = all.stream().filter(item -> item.getParentId()==pnode.getId())
                .collect(Collectors.toList());
        if (subNodes == null || subNodes.size() == 0) {
            return;
        }
        pnode.setChildren(new ArrayList<TMenu>());
        for (TMenu item : subNodes) {
            TMenu combotreeVo = new TMenu();
            combotreeVo.setId(item.getId());
            combotreeVo.setMenuName(item.getMenuName());
            combotreeVo.setParentId(item.getParentId());
            combotreeVo.setMenuUrl(item.getMenuUrl());
            fillSubNode(combotreeVo, all);
            if (combotreeVo.getChildren() != null && combotreeVo.getChildren().size() > 0) {
                combotreeVo.setStatus(0);
            } else {
                combotreeVo.setStatus(1);
            }
            pnode.getChildren().add(combotreeVo);
        }
    }

3.退出

	@ApiOperation(value = "退出", httpMethod = "POST")
    @RequestMapping(value = "/logout")
    @ResponseBody
    public CommonResult logout(@RequestParam(value = "token", required = true) String token) {
		RcSysUserEntity byToken = rcSysUserRepository.findByToken(token);
		if (byToken == null) return CommonResult.failed("token参数异常!");
		byToken.setToken("");
		rcSysUserRepository.save(byToken);
		return CommonResult.success("退出成功!");
    }

4.角色和权限实体类

package com.zkdj.data.entity.pojo;

import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import javax.persistence.*;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 * @description 系统角色权限表
 * @author gxf
 * @date 2023-06-02
 */
@Entity
@Data
@Table(name="t_sys_menu")
@ApiModel("系统角色权限表")
public class TMenu implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * 主键
     */
    @Id
    @ApiModelProperty("主键")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", nullable = false)
    private Integer id;

    /**
     * 菜单名称
     */
    @ApiModelProperty("菜单名称")
    @Column(name="menu_name")
    private String menuName;

    /**
     * 父级id
     */
    @ApiModelProperty("父级id")
    @Column(name="parent_id")
    private Integer parentId;

    /**
     * 菜单路径
     */
    @ApiModelProperty("菜单路径")
    @Column(name="menu_url")
    private String menuUrl;

    /**
     * 创建时间
     */
    @ApiModelProperty("创建时间")
    @Column(name="ctime")
    private String ctime;

    /**
     * 修改时间
     */
    @ApiModelProperty("修改时间")
    @Column(name="utime")
    private String utime;

    /**
     * 状态 : 0 未启用 1 已启用
     */
    @ApiModelProperty("状态 : 0 未启用 1 已启用")
    @Column(name="status")
    private Integer status;

    /**
     * 排序
     */
    @ApiModelProperty("排序")
    @Column(name="sort")
    private Integer sort;

    /**
     * 是否是父级 0 不是 1是
     */
    @ApiModelProperty("是否是父级 0 不是 1是")
    @Column(name="is_parent")
    private Integer isParent;

    /** 子节点 */
    @JsonInclude(JsonInclude.Include.NON_EMPTY)
    @Transient
    private List<TMenu> children=new ArrayList<>();

    public TMenu() {
    }


    public TMenu(TMenu tMenu) {
    }
}
package com.zkdj.data.entity.pojo;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import javax.persistence.*;
import java.io.Serializable;
/**
 * @description 系统角色表
 * @author gxf
 * @date 2023-05-29
 */
@Entity
@Data
@Table(name="t_sys_role")
@ApiModel("系统角色表")
public class TRole implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * 主键
     */
    @Id
    @ApiModelProperty("主键")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", nullable = false)
    private Integer id;

    /**
     * 角色名称
     */
    @ApiModelProperty("角色名称")
    @Column(name="role_name")
    private String roleName;

    /**
     * 角色标识
     */
    @ApiModelProperty("角色标识")
    @Column(name="role_type")
    private String roleType;

    /**
     * 角色描述
     */
    @ApiModelProperty("角色描述")
    @Column(name="role_descrip")
    private String roleDescrip;

    /**
     * 创建时间
     */
    @ApiModelProperty("创建时间")
    @Column(name="ctime")
    private String ctime;

    /**
     * 修改时间
     */
    @ApiModelProperty("修改时间")
    @Column(name="utime")
    private String utime;

    /**
     * 角色权限ids
     */
    @ApiModelProperty("角色权限ids")
    @Column(name="menu_ids")
    private String menuIds;

    public TRole() {
    }

}

5.Jwt工具类

package com.zkdj.data.common.config.jwt.payload;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import com.zkdj.data.entity.model.RcSysUserEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import java.util.Map;

/**
 * @author Administrator
 */
@Data
@ApiModel("jwt")
public class JwtPayLoad  {

    private static final long serialVersionUID = 1L;

    @ApiModelProperty("过期时间")
    private String expTime;

    /**
     * 主键
     */
    @Id
    @ApiModelProperty("主键")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    /**
     * 账号
     */
    @ApiModelProperty("账号")
    private String account;

    /**
     * 密码
     */
    @ApiModelProperty("密码")
    private String password;

    /**
     * 真实姓名
     */
    @ApiModelProperty("真实姓名")
    private String realname;

    /**
     * 角色id
     */
    @ApiModelProperty("角色id")
    private String roleId;

    /**
     * 盐值
     */
    @ApiModelProperty("盐值")
    private String salt;

    /**
     * 类型
     */
    @ApiModelProperty("类型")
    private Integer type;

    /**
     * 创建时间
     */
    @ApiModelProperty("创建时间")
    private String ctime;

    /**
     * 创建用户
     */
    @ApiModelProperty("创建用户")
    private String cuser;

    /**
     * 更新时间
     */
    @ApiModelProperty("更新时间")
    private String utime;

    /**
     * 令牌
     */
    @ApiModelProperty("令牌")
    private String token;

    /**
     * 电话
     */
    @ApiModelProperty("电话")
    private String tel;

    /**
     * 邮箱
     */
    @ApiModelProperty("邮箱")
    private String email;

    /**
     * 启用禁用 0禁用1启用
     */
    @ApiModelProperty("启用禁用 0禁用1启用")
    private Integer status;



    /**
     * 用户的键
     */
    private String userKey;

    public JwtPayLoad() {
    }

    public JwtPayLoad(Long id, String roleId, String account, String realname) {
        this.id = id;
        this.roleId = roleId;
        this.account = account;
        this.realname = realname;
    }

    public JwtPayLoad(
            Long id, String roleId, String account, String realname,String expTime,String password,String salt,
       Integer type,String ctime,String cuser,String utime,String token,String tel,String email,Integer status,String userKey) {
        this.id = id;
        this.roleId = roleId;
        this.account = account;
        this.realname = realname;
        this.expTime = expTime;
        this.password = password;
        this.salt = salt;
        this.type = type;
        this.ctime = ctime;
        this.ctime = ctime;
        this.cuser = cuser;
        this.utime = utime;
        this.token = token;
        this.tel = tel;
        this.email = email;
        this.status = status;
        this.userKey = userKey;
    }

    /**
     * payload转化为map形式
     *
     * @Date 2023/7/20 20:50
     */
    public Map<String, Object> toMap() {
        Map<String, Object> map = BeanUtil.beanToMap(new JwtPayLoad(id, roleId, account, realname, expTime, password, salt,
                type, ctime, cuser, utime, token, tel, email, status, userKey), false, true);
        return map;
    }

    /**
     * payload转化为map形式
     *
     * @Date 2023/7/20 20:50
     */

    public static JwtPayLoad toBean(Map<String, Object> map) {
        if (map == null || map.size() == 0) {
            return new JwtPayLoad();
        } else {
            JwtPayLoad jwtPayLoad = BeanUtil.mapToBean(map, JwtPayLoad.class, true, new CopyOptions());
            return jwtPayLoad;
        }
    }
}

/**
 * Copyright 2018-2020 stylefeng & fengshuonan (sn93@qq.com)
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.zkdj.data.common.config.jwt;


import com.zkdj.data.common.config.jwt.payload.JwtPayLoad;
import com.zkdj.data.utils.UUIDUtil;
import com.zkdj.data.utils.date.DateUtil;
import io.jsonwebtoken.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.Map;

/**
 * <p>jwt token工具类</p>
 * <pre>
 *     jwt的claim里一般包含以下几种数据:
 *         1. iss -- token的发行者
 *         2. sub -- 该JWT所面向的用户
 *         3. aud -- 接收该JWT的一方
 *         4. exp -- token的失效时间
 *         5. nbf -- 在此时间段之前,不会被处理
 *         6. iat -- jwt发布时间
 *         7. jti -- jwt唯一标识,防止重复使用
 * </pre>
 */
public class JwtTokenUtil {

    static Integer DEFAULTSECS = 60*60*12;  //默认过期时间10分钟

    private final static String DEFAULT_SECRET="eyJhbGciOiJIUzUxMiJ9";
    public final static String FORMAT="yyyy-MM-dd HH:mm:ss";

    /**
     * 生成token
     */
    public static String createToken(JwtPayLoad jwtPayLoad) {
        Integer expiredSeconds = DEFAULTSECS;
        Date expirationDate = new Date(System.currentTimeMillis() + expiredSeconds * 1000);
        if(StringUtils.isNotBlank(jwtPayLoad.getExpTime())){
            expirationDate = DateUtil.getDateFormateStr(jwtPayLoad.getExpTime(),FORMAT);
        }
        jwtPayLoad.setExpTime(DateUtil.getDateTimeConvertStr(expirationDate,FORMAT));
        return generateToken(String.valueOf(jwtPayLoad.getId()),expirationDate,jwtPayLoad.toMap());
    }

    /**
     * 获取解析当前登录的用户token信息
     * @return
     */
    public static JwtPayLoad getTokenJwtPayLoadInfo() {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        return JwtTokenUtil.getJwtPayLoad( request.getHeader("token"));
    }
    /**
     * 获取jwt的payload部分
     */
    public static JwtPayLoad getJwtPayLoad(String token) {
        Claims claimFromToken = getClaimFromToken(token);
        return JwtPayLoad.toBean(claimFromToken);
    }

    /**
     * 解析token是否正确(true-正确, false-错误)
     */
    public static Boolean checkToken(String token) {
        try {
            Jwts.parser().setSigningKey(DEFAULT_SECRET).parseClaimsJws(token).getBody();
            return true;
        } catch (JwtException e) {
            return false;
        }
    }

    /**
     * 验证token是否失效
     */
    public static Boolean isTokenExpired(String token) {
        try {
            final Date expiration = getExpirationDateFromToken(token);
            if(null==expiration){
                return true;
            }
            return expiration.before(new Date());
        } catch (ExpiredJwtException expiredJwtException) {
            return true;
        }
    }

    /**
     * 获取jwt失效时间
     */
    public static Date getExpirationDateFromToken(String token) {
        try {
            return getClaimFromToken(token).getExpiration();
        }catch (Exception ex){
            return null;
        }
    }

    /**
     * 生成token 核心方法
     */
    public static String generateToken(String userId, Date expiredDate, Map<String, Object> claims) {
        final Date createdDate = new Date();
        if (claims == null) {
            return Jwts.builder()
                    .setSubject(userId)
                    .setIssuedAt(createdDate)
                    .setExpiration(expiredDate)
                    .signWith(SignatureAlgorithm.HS256, DEFAULT_SECRET)
                    .compact();
        } else {
            return Jwts.builder()
                    .setClaims(claims)
                    .setSubject(userId)
                    .setIssuedAt(createdDate)
                    .setExpiration(expiredDate)
                    .signWith(SignatureAlgorithm.HS256, DEFAULT_SECRET)
                    .compact();
        }
    }

    /**
     * 获取jwt的payload部分
     */
    public static Claims getClaimFromToken(String token) {
        if (StringUtils.isEmpty(token)) {
            throw new IllegalArgumentException("token参数为空!");
        }
        return Jwts.parser()
                .setSigningKey(DEFAULT_SECRET)
                .parseClaimsJws(token)
                .getBody();
    }
    public static void main(String[] args) {
        System.out.println(UUIDUtil.get32UUID());
        JwtPayLoad payLoad=new JwtPayLoad();
//        payLoad.setUserId("103");
//        payLoad.setExpTime("2021-12-26 23:50:50");
        payLoad.setToken("eyJhbGciOiJIUzI1NiJ9.eyJleHBUaW1lIjoiMjAyMy0wNi0wMiAwMzowNjowMiIsImlkIjo0LCJhY2NvdW50IjoiemtkaiIsInJlYWxuYW1lIjoiemtkaiIsInJvbGVJZCI6IjEiLCJjdGltZSI6IjIwMjMtMDUtMzEgMTg6MDA6NDMiLCJjdXNlciI6InprZGoiLCJ0ZWwiOiIxODYxMDA4NjEwMCIsImVtYWlsIjoiMTAwMDBAcXEuY29tIiwic3ViIjoiNCIsImlhdCI6MTY4NTYwMzE2MiwiZXhwIjoxNjg1NjQ2MzYyfQ.2pI28yqsG43gRkbsUv5UyH4OqSff3w3IASmNmF7lJRo");
        payLoad.setId(1L);
        String jwtsecret = "";
        String s = JwtTokenUtil.createToken(payLoad);
//        String s = "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMDMiLCJleHBUaW1lIjoiMjAyMS0xMi0xMSAwMDo1MDo1MCIsImN1c3RvbWVySWQiOm51bGwsInVzZXJOYW1lIjpudWxsLCJleHAiOjE2MzkxNTUwNTAsInVzZXJJZCI6IjEwMyIsImlhdCI6MTYzOTE1NDE0NiwiY3VzdG9tZXJOYW1lIjpudWxsfQ.WUlQlhG7DQUkMFNzm-uwD4lVCyeeNmRXY05tSeKYuEc";
//        JwtPayLoad jwtPayLoad = getJwtPayLoad("eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMDUiLCJleHBUaW1lIjoiMjAyMS0xMi0yNyAyMTozNzowOCIsImN1c3RvbWVySWQiOm51bGwsInVzZXJOYW1lIjoieHlneHEiLCJleHAiOjE2NDA2MTIyMjgsInVzZXJJZCI6IjEwNSIsImlhdCI6MTY0MDYxMTYyOCwiY3VzdG9tZXJOYW1lIjpudWxsfQ.8lazFHdMdQP5K-iJCGdflCBZnlNOilXVSuGcA0mU1A0");
        JwtPayLoad jwtPayLoad = getJwtPayLoad(s);
        System.out.println("Secret:"+ jwtPayLoad.getToken());
        System.out.println("token是否正确:"+ JwtTokenUtil.checkToken(s)+jwtPayLoad.getExpTime());
        System.out.println("token是否失效:"+ JwtTokenUtil.isTokenExpired(s));
        System.out.println("token过期日期:"+ DateUtil.getDateTimeConvertStr(JwtTokenUtil.getExpirationDateFromToken(s),"yyyy-MM-dd HH:mm:ss"));
    }
}

权限
权限
角色
角色
用户
在这里插入图片描述

其他工具类见上篇文章

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

10000guo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值