基于用户认证的前后端实现

161 篇文章 16 订阅

一 准备

1 引入依赖

common-util中引入jwt依赖

<!-- JWT相关依赖-->
<dependencies>
    <dependency>
        <groupId>io.jsonwebtoken</groupId>
        <artifactId>jjwt</artifactId>
    </dependency>
    <dependency>
        <groupId>joda-time</groupId>
        <artifactId>joda-time</artifactId>
    </dependency>
</dependencies>

2 引入工具类

common-util中引入工具类:JwtUtils.java、JwtInfo.java

JwtUtils.java

public class JwtUtils {
    /**
     * 密钥字符串
     */
    public static final String APP_SECRET = "ukc8BDbRigUDaY6pZFfWus2jZWLPHO";

    /**
     * 功能描述:获得密钥实例
     *
     * @return Key 密钥实例
     * @author cakin
     * @date 2020/12/27
     */
    private static Key getKeyInstance() {
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        byte[] bytes = DatatypeConverter.parseBase64Binary(APP_SECRET);
        return new SecretKeySpec(bytes, signatureAlgorithm.getJcaName());
    }

    /**
     * 功能描述:获取Jwt的token
     *
     * @param jwtInfo 用户信息
     * @param expire 过期时间
     * @return String
     * @author cakin
     * @date 2020/12/27
     */
    public static String getJwtToken(JwtInfo jwtInfo, int expire) {
        String JwtToken = Jwts.builder()
                .setHeaderParam("typ", "JWT")
                .setHeaderParam("alg", "HS256")
                .setSubject("guli-user") // 主题
                .setIssuedAt(new Date()) // 颁发时间
                .setExpiration(DateTime.now().plusSeconds(expire).toDate()) // 过期时间
                .claim("id", jwtInfo.getId()) // 用户id
                .claim("nickname", jwtInfo.getNickname()) // 用户昵称
                .claim("avatar", jwtInfo.getAvatar()) // 用户头像
                .signWith(SignatureAlgorithm.HS256, getKeyInstance())
                .compact();
        return JwtToken;
    }

    /**
     * 判断token是否存在与有效
     *
     * @param jwtToken jwtToken
     * @return boolean 是否有效
     */
    public static boolean checkJwtTToken(String jwtToken) {
        if (StringUtils.isEmpty(jwtToken)) return false;
        try {
            Jwts.parser().setSigningKey(getKeyInstance()).parseClaimsJws(jwtToken);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 判断token是否存在与有效
     *
     * @param request http请求
     * @return boolean JWT是否有效
     */
    public static boolean checkJwtTToken(HttpServletRequest request) {
        try {
            String jwtToken = request.getHeader("token");
            if (StringUtils.isEmpty(jwtToken)) return false;
            Jwts.parser().setSigningKey(getKeyInstance()).parseClaimsJws(jwtToken);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }


    /**
     * 根据token获取会员id
     *
     * @param request http请求
     * @return JwtInfo JWt中的会员信息
     */
    public static JwtInfo getMemberIdByJwtToken(HttpServletRequest request) {
        String jwtToken = request.getHeader("token");
        if (StringUtils.isEmpty(jwtToken)) return null;
        Jws<Claims> claimsJws = Jwts.parser().setSigningKey(getKeyInstance()).parseClaimsJws(jwtToken);
        Claims claims = claimsJws.getBody();
        JwtInfo jwtInfo = new JwtInfo(claims.get("id").toString(), claims.get("nickname").toString(), claims.get("avatar").toString());
        return jwtInfo;
    }
}

JwtInfo.java

@Data
@AllArgsConstructor
@NoArgsConstructor
public class JwtInfo {
    /**
     * 用户id
     */
    private String id;
    /**
     * 昵称
     */
    private String nickname;
    /**
     * 图像
     */
    private String avatar;
    //权限、角色等
    //不要存敏感信息
}

二 用户登录接口

1 定义LoginVo

/**
* @className: LoginVo
* @description: 用户登录信息
* @date: 2020/12/27
* @author: cakin
*/
@Data
public class LoginVo implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * 手机号
     */
    private String mobile;
    /**
     * 用户密码
     */
    private String password;
}

2 service实现登录

接口:MemberService

/**
* 功能描述:登录接口
*
* @author cakin
* @date 2020/12/27
* @param loginVo 用户登录信息
* @return String Jwt token
*/
String login(LoginVo loginVo);

实现: MemberServiceImpl

/**
* 功能描述:登录接口
*
* @param loginVo 用户登录信息
* @return String Jwt token
* @author cakin
* @date 2020/12/27
*/
@Override
public String login(LoginVo loginVo) {
    String mobile = loginVo.getMobile();
    String password = loginVo.getPassword();
    // 校验:参数(手机号、密码)是否合法
    if (StringUtils.isEmpty(mobile)
            || !FormUtils.isMobile(mobile)
            || StringUtils.isEmpty(password)) {
        throw new GuliException(ResultCodeEnum.PARAM_ERROR);
    }
    // 校验手机号是否存在
    QueryWrapper<Member> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("mobile", mobile);
    Member member = baseMapper.selectOne(queryWrapper);
    if (member == null) {
        throw new GuliException(ResultCodeEnum.LOGIN_MOBILE_ERROR);
    }
    // 校验密码是否正确
    if (!MD5.encrypt(password).equals(member.getPassword())) {
        throw new GuliException(ResultCodeEnum.LOGIN_PASSWORD_ERROR);
    }
    // 校验用户是否被禁用
    if (member.getDisabled()) {
        throw new GuliException(ResultCodeEnum.LOGIN_DISABLED_ERROR);
    }
    // 登录:生成token
    JwtInfo info = new JwtInfo();
    info.setId(member.getId());
    info.setNickname(member.getNickname());
    info.setAvatar(member.getAvatar());
    String jwtToken = JwtUtils.getJwtToken(info, 1800);
    return jwtToken;
}

3 登录接口

/**
* 功能描述:登录接口
*
* @author cakin
* @date 2020/12/27
* @param loginVo 登录信息
* @return R 返回给前端的信息
*/
@ApiOperation(value = "会员登录")
@PostMapping("login")
public R login(@RequestBody LoginVo loginVo){
    String token = memberService.login(loginVo);
    return R.ok().data("token", token).message("登录成功");
}

三 前端整合

1 安装cookie模块

npm install js-cookie@2.2.0

2 api

import request from '~/utils/request'
// import cookie from 'js-cookie'
// 提交登录信息
export default {
  submitLogin(user) {
    return request({
      baseURL: 'http://localhost:8160',
      url: '/api/ucenter/member/login',
      method: 'post',
      data: user
    })
  },
}

3 登录页核心代码

import cookie from 'js-cookie'
import loginApi from '~/api/login'
export default {
  layout: 'sign',
  data() {
    return {
      user: {
        mobile: '',
        password: ''
      }
    }
  },
  methods: {
    // 登录
    submitLogin() {
      // 执行远程登录接口调用
      loginApi.submitLogin(this.user).then(response => {
        // 将jwt写入cookie
        cookie.set('guli_jwt_token', response.data.token, { domain: 'localhost' })
        // 跳转到网站的首页面
        window.location.href = '/'
      })
    }
  }
}
</script>

4 测试

查看cookie中存储了jwtToken值

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值