jwt实现token

pull/2/head
2991692032 2 months ago
parent f8cd2a11f8
commit 155c336835

@ -49,7 +49,12 @@
<artifactId>hutool-all</artifactId> <artifactId>hutool-all</artifactId>
<version>5.8.16</version> <version>5.8.16</version>
</dependency> </dependency>
<!-- jwt-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<!-- redis--> <!-- redis-->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>

@ -0,0 +1,29 @@
package com.unilife.config;
import com.unilife.interceptor.JwtInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Autowired
private JwtInterceptor jwtInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(jwtInterceptor).addPathPatterns("/**")
.excludePathPatterns(
"/users/login",
"/users/register",
"/users/code",
"/users/login/code",
"/swagger-resources/**",
"/v2/api-docs/**",
"/doc.html",
"/webjars/**"
);
}
}

@ -2,19 +2,26 @@ package com.unilife.controller;
import com.unilife.common.result.Result; import com.unilife.common.result.Result;
import com.unilife.model.dto.EmailDTO; import com.unilife.model.dto.EmailDTO;
import com.unilife.model.dto.LogDTO;
import com.unilife.model.dto.LoginDTO; import com.unilife.model.dto.LoginDTO;
import com.unilife.model.dto.LoginEmailDTO; import com.unilife.model.dto.LoginEmailDTO;
import com.unilife.model.dto.RegisterDTO;
import com.unilife.model.vo.LoginVO;
import com.unilife.model.vo.RegisterVO;
import com.unilife.service.UserService; import com.unilife.service.UserService;
import com.unilife.utils.BaseContext;
import com.unilife.utils.JwtUtil;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import java.time.Duration;
@Api(tags = "用户管理") @Api(tags = "用户管理")
@RestController @RestController
@ -24,16 +31,34 @@ public class UserController {
@Autowired @Autowired
private UserService userService; private UserService userService;
@Autowired
private JwtUtil jwtUtil;
@Autowired
private StringRedisTemplate stringRedisTemplate;
@ApiOperation(value = "用户注册") @ApiOperation(value = "用户注册")
@PostMapping("register") @PostMapping("register")
public Result register(@RequestBody LoginDTO loginDTO) { public Result register(@RequestBody RegisterDTO registerDTO) {
return userService.register(loginDTO); return userService.register(registerDTO);
} }
@ApiOperation(value = "用户登录") @ApiOperation(value = "用户登录")
@PostMapping("login") @PostMapping("login")
public Result login(@RequestBody LogDTO logDTO) { return userService.login(logDTO); } public Result login(@RequestBody LoginDTO loginDTO) {
Result login = userService.login(loginDTO);
//登陆成功后生成jwt令牌
LoginVO vo=(LoginVO) login.getData();
if (vo == null) {
return login;
}
Long id = vo.getId();
String token = jwtUtil.generateToken(id);
vo.setToken(token);
//Threadlocal保存当前用户id
BaseContext.setId(id);
return Result.success(vo);
}
@ApiOperation(value = "获取邮箱验证码") @ApiOperation(value = "获取邮箱验证码")
@PostMapping("code") @PostMapping("code")

@ -0,0 +1,54 @@
package com.unilife.interceptor;
import cn.hutool.core.util.StrUtil;
import com.unilife.utils.BaseContext;
import com.unilife.utils.JwtUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Component
@Slf4j
public class JwtInterceptor implements HandlerInterceptor {
@Autowired
private JwtUtil jwtUtil;
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
log.info("JwtInterceptor preHandle");
String token = request.getHeader("Authorization");
if(StrUtil.isBlank(token)){
response.setStatus(401);
return false;
}
boolean verified = jwtUtil.verifyToken(token);
if (!verified) {
response.setStatus(401);
return false;
}
//从token中获取userid并存入threadlocal
Long userId = jwtUtil.getUserIdFromToken(token);
BaseContext.setId(userId);
return true;
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
BaseContext.removeId();
}
}

@ -1,19 +1,14 @@
package com.unilife.model.dto; package com.unilife.model.dto;
//这个是注册的DTO //这个才是登录的DTO
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
@Data @Data
@AllArgsConstructor
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor
public class LoginDTO { public class LoginDTO {
private String username;
private String email; private String email;
private String password; private String password;
private String nickname;
private String studentId;
private String department;
private String major;
private String grade;
} }

@ -0,0 +1,19 @@
package com.unilife.model.dto;
//这个是注册的DTO
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class RegisterDTO {
private String username;
private String email;
private String password;
private String nickname;
private String studentId;
private String department;
private String major;
private String grade;
}

@ -1,27 +0,0 @@
package com.unilife.model.vo;
import com.unilife.model.entity.User;
import lombok.Data;
@Data
public class LogVO {
private Integer id;
private String username;
private String nickname;
private String avatar;
private Byte role;
private Byte isVerified;
private Byte status;
public LogVO(Integer id,String username,String nickname,String avatar,Byte role,Byte isVerified,Byte status)
{
this.id = id;
this.username = username;
this.nickname = nickname;
this.avatar = avatar;
this.role = role;
this.isVerified = isVerified;
}
}

@ -1,17 +1,21 @@
package com.unilife.model.vo; package com.unilife.model.vo;
import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor;
@Data @Data
@AllArgsConstructor
@NoArgsConstructor
public class LoginVO { public class LoginVO {
private Integer id; private Long id;
private String username; private String username;
private String nickname; private String nickname;
private String avatar;
private Byte role;
private Byte isVerified;
private Byte status;
private String token;
public LoginVO(Integer id, String username, String nickname)
{
this.id = id;
this.username = username;
this.nickname = nickname;
}
} }

@ -1,14 +1,15 @@
package com.unilife.model.dto; package com.unilife.model.vo;
//这个才是登录的DTO
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
@Data @Data
@NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public class LogDTO { @NoArgsConstructor
private String email; public class RegisterVO {
private String password; private Long id;
private String username;
private String nickname;
} }

@ -1,18 +1,16 @@
package com.unilife.service; package com.unilife.service;
import com.unilife.common.result.Result; import com.unilife.common.result.Result;
import com.unilife.model.dto.LogDTO;
import com.unilife.model.dto.LoginDTO; import com.unilife.model.dto.LoginDTO;
import com.unilife.model.dto.LoginEmailDTO; import com.unilife.model.dto.LoginEmailDTO;
import com.unilife.model.dto.RegisterDTO;
public interface UserService { public interface UserService {
Result register(LoginDTO loginDTO); Result register(RegisterDTO registerDTO);
Result login(LogDTO logDTO); Result login(LoginDTO loginDTO);
Result sendVerificationCode(String email); Result sendVerificationCode(String email);
Result loginWithEmail(LoginEmailDTO loginEmailDTO); Result loginWithEmail(LoginEmailDTO loginEmailDTO);
} }

@ -2,17 +2,17 @@ package com.unilife.service.impl;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.RandomUtil; import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.unilife.common.constant.RedisConstant; import com.unilife.common.constant.RedisConstant;
import com.unilife.common.result.Result; import com.unilife.common.result.Result;
import com.unilife.mapper.UserMapper; import com.unilife.mapper.UserMapper;
import com.unilife.model.dto.LogDTO;
import com.unilife.model.dto.LoginDTO; import com.unilife.model.dto.LoginDTO;
import com.unilife.model.dto.LoginEmailDTO; import com.unilife.model.dto.LoginEmailDTO;
import com.unilife.model.dto.RegisterDTO;
import com.unilife.model.entity.User; import com.unilife.model.entity.User;
import com.unilife.model.vo.LogVO;
import com.unilife.model.vo.LoginVO; import com.unilife.model.vo.LoginVO;
import com.unilife.model.vo.RegisterVO;
import com.unilife.service.UserService; import com.unilife.service.UserService;
import com.unilife.utils.JwtUtil;
import com.unilife.utils.RegexUtils; import com.unilife.utils.RegexUtils;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -27,7 +27,6 @@ import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMessage;
import java.time.Duration; import java.time.Duration;
import java.time.LocalDateTime;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -52,37 +51,38 @@ public class UserServiceImpl implements UserService {
final int CODE_EXPIRE_MINUTES = 10; final int CODE_EXPIRE_MINUTES = 10;
final int LIMIT_SECONDS=60; final int LIMIT_SECONDS=60;
@Autowired
private JwtUtil jwtUtil;
@Override @Override
public Result register(LoginDTO loginDTO) { public Result register(RegisterDTO registerDTO) {
if(loginDTO.getEmail().equals("") || loginDTO.getPassword().equals("")) { if(registerDTO.getEmail().isEmpty() || registerDTO.getPassword().isEmpty()) {
return Result.error(400,"邮箱或密码不能为空"); return Result.error(400,"邮箱或密码不能为空");
} }
User user = new User(); User user = new User();
BeanUtil.copyProperties(loginDTO,user); BeanUtil.copyProperties(registerDTO,user);
userMapper.insert(user); userMapper.insert(user);
LoginVO loginVO = new LoginVO(Math.toIntExact(user.getId()),user.getUsername(),user.getNickname()); RegisterVO registerVO = new RegisterVO(user.getId(),user.getUsername(),user.getNickname());
return Result.success(loginVO); return Result.success(registerVO);
} }
@Override @Override
public Result login(LogDTO logDTO) { public Result login(LoginDTO loginDTO) {
User user = new User(); User user = new User();
BeanUtil.copyProperties(logDTO,user);//将登录的前端传来的消息拷贝给这个user BeanUtil.copyProperties(loginDTO,user);//将登录的前端传来的消息拷贝给这个user
User getuser = userMapper.FindByEmail(user.getEmail(),user.getPassword()); User getuser = userMapper.FindByEmail(user.getEmail(),user.getPassword());
if(getuser == null) if(getuser == null)
{ {
return Result.error(logDTO,"用户不存在,登录失败!"); return Result.error(loginDTO,"用户不存在,登录失败!");
} }
if(!user.getPassword().equals(getuser.getPassword())) if(!user.getPassword().equals(getuser.getPassword()))
{ {
return Result.error(logDTO,"密码错误,登录失败!"); return Result.error(loginDTO,"密码错误,登录失败!");
} }
LogVO logVO = new LogVO(Math.toIntExact(getuser.getId()), getuser.getUsername(), getuser.getNickname(), LoginVO loginVO=new LoginVO();
getuser.getAvatar(), getuser.getRole(), getuser.getIsVerified(), getuser.getStatus()); BeanUtil.copyProperties(getuser,loginVO);
return Result.success(logVO); return Result.success(loginVO);
} }
@Override @Override
@ -178,12 +178,13 @@ public class UserServiceImpl implements UserService {
} }
//6.生成登录凭证 //6.生成登录凭证
//TODO String token=jwtUtil.generateToken(user.getId());
// 8. 返回用户信息和登录凭证 // 8. 返回用户信息和登录凭证
Map<String, Object> userInfo = new HashMap<>(); Map<String, Object> userInfo = new HashMap<>();
//HashMap userInfo.put("token", token); //HashMap userInfo.put("token", token);
userInfo.put("user", user); userInfo.put("user", user);
userInfo.put("token", token);
return Result.success(userInfo); return Result.success(userInfo);
} }

@ -0,0 +1,19 @@
package com.unilife.utils;
public class BaseContext {
public static ThreadLocal<Long> threadLocal = new ThreadLocal<>();
public static void setId(Long id) {
threadLocal.set(id);
}
public static Long getId() {
return threadLocal.get();
}
public static void removeId() {
threadLocal.remove();
}
}

@ -0,0 +1,45 @@
package com.unilife.utils;
import cn.hutool.core.date.DateTime;
import cn.hutool.jwt.JWTUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
@Component
public class JwtUtil {
@Value("${jwt.secret}")
private String secret;
@Value("${jwt.expiration}")
public long expiration;
public String generateToken(Long id) {
DateTime now = DateTime.now();
DateTime expireTime = new DateTime(now.getTime() + expiration * 1000);
Map<String, Object> payload = new HashMap<>();
payload.put("userId", id);
payload.put("created",now.getTime());
return JWTUtil.createToken(payload,secret.getBytes());
}
public boolean verifyToken(String token) {
try{
JWTUtil.verify(token,secret.getBytes());
return true;
}catch (Exception e){
return false;
}
}
public Long getUserIdFromToken(String token) {
try {
return (Long)JWTUtil.parseToken(token).getPayload("userId");
}catch (Exception e){
return null;
}
}
}

@ -2,7 +2,7 @@ server:
port: 8084 port: 8084
spring: spring:
datasource: datasource:
url: jdbc:mysql://localhost:3306/UniLife?useSSL=false&serverTimezone=UTC&characterEncoding=UTF-8 url: jdbc:mysql://localhost:3306/UniLife?allowPublicKeyRetrieval=true&useSSL=false&serverTimezone=UTC&characterEncoding=UTF-8
username: root username: root
password: 123456 password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver driver-class-name: com.mysql.cj.jdbc.Driver
@ -47,4 +47,7 @@ mybatis:
map-underscore-to-camel-case: true map-underscore-to-camel-case: true
logging: logging:
level: level:
com.unilife: debug com.unilife: debug
jwt:
secret: qwertyuiopasdfghjklzxcvbnm
expiration: 86400
Loading…
Cancel
Save