使用JWT生成Token
1、创建springboot项目
2、添加pom依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--springboot test-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--jpa-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>false</optional><!--依赖是否被传递 -->
</dependency>
<!--redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-redis</artifactId>
<version>1.4.5.RELEASE</version>
</dependency>
<!--fastjson-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.31</version>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!--swagger-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.6.1</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.6.1</version>
</dependency>
<!--jwt-->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.3.0</version>
</dependency>
3、SwaggerUI配置
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket docket() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.example.redis"))
.build();
}
private ApiInfo apiInfo(){
return new ApiInfoBuilder()
.title("SpringBoot接口")
.version("0.1")
.description(null)
.build();
}
}
4、application.properties配置
#redis
spring.redis.database=0
spring.redis.host=xx.xx.xx.xx
spring.redis.port=6379
spring.redis.password=xx
spring.datasource.url=jdbc:mysql://xx/xx?useSSL=false&useUnicode=true&characterEncoding=utf8
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.username=xx
spring.datasource.password=xx
5、redis配置
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, String> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
return redisTemplate;
}
}
6、JWT生成Token类
public class JwtUtil {
//秘钥
public static final String SECRET = "Guesswho";
//过期时间
public static final int EXPIRE = 5;
/**
* 由字符串生成加密key
*/
public static SecretKey generateKey(String secretKey) {
Charset charset = Charset.forName("utf-8");
Encoder encoder = Base64.getEncoder();
byte[] encodedKey = encoder.encode(secretKey.getBytes(charset));
SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");// 根据给定的字节数组使用AES加密算法构造一个密钥,使用 encodedKey中的始于且包含 0 到前 leng 个字节。
return key;
}
//生成jwt token
public static String createToken(int userId) throws UnsupportedEncodingException {
Calendar nowTime = Calendar.getInstance();
nowTime.add(Calendar.HOUR, EXPIRE);
Date expireDate = nowTime.getTime();
Map<String, Object> map = new HashMap<>();
map.put("alg", "HS256");
map.put("typ", "JWT");
String token = JWT.create()
.withHeader(map)//头
.withClaim("userId", userId)
.withIssuedAt(new Date())//签名时间
.withExpiresAt(expireDate)//过期时间
.sign(Algorithm.HMAC256(SECRET));//签名
return token;
}
/*
* 验证token
* */
public static Map<String, Claim> verifyToken(String token) throws Exception {
JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SECRET)).build();
DecodedJWT jwt = null;
try {
jwt = verifier.verify(token);
} catch (Exception e) {
throw new Exception("token过期,请重新登陆");
}
return jwt.getClaims();
}
/*
* 解析token
* */
public static Map<String, Claim> parseToken(String token) {
DecodedJWT jwt = JWT.decode(token);
return jwt.getClaims();
}
}
7、创建User实体类
@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = false)
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String username;
private String password;
private String salt;
}
用户的Model类
@Data
public class UserModel {
@ApiModelProperty(value = "用户姓名",required = true,example = "hello")
@NotBlank
String username;
@ApiModelProperty(value = "用户密码",required = true,example = "Guess")
@NotBlank
String password;
}
创建密码盐对密码加密的接受类
@Data
public class SaltAndPassword {
private String mixedPassword;
private String salt;
public SaltAndPassword(String mixedPassword, String salt) {
this.mixedPassword = mixedPassword;
this.salt = salt;
}
}
密码盐
public class PasswordUtil {
/**
* 使用指定密码盐对密码进行加密
*/
public static String mix(String password, String salt) {
String newPassword = DigestUtils.md5Hex(password) + salt;
return DigestUtils.md5Hex(newPassword);
}
/*
* 使用随机密码盐对密码加密
* */
public static SaltAndPassword mix(String password) {
String salt = getRandomString(4);
String mixPassword = mix(password,salt);
return new SaltAndPassword(mixPassword,salt);
}
/**
* 生成随机字符串
*/
public static String getRandomString(int length) {
Random random = new Random();
StringBuffer stringBuffer = new StringBuffer();
for (int i = 0; i < length; i++) {
int num = random.nextInt(3);
long result = 0;
switch (num) {
case 0:
result = Math.round(Math.random() * 25 + 65);
stringBuffer.append(String.valueOf((char) result));
break;
case 1:
result = Math.round(Math.random() * 25 + 97);
stringBuffer.append(String.valueOf((char) result));
break;
case 2:
stringBuffer.append(String.valueOf(new Random().nextInt(10)));
break;
}
}
return stringBuffer.toString();
}
}
8、Dao层
public interface UserRepository extends JpaRepository<User,Integer> {
User findUserByUsername(String username);
User findUserById(int id);
}
9、service层
public interface UserService {
String login(String username, String password) throws Exception;
User register(String name,String password) throws Exception;
User findUserById(int id);
User validUser(String name,String password) throws Exception;
String getTokenEntity(User user);
}
10、serviceImpl
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserRepository userRepository;
@Override
public String login(String username, String password) throws Exception {
//验证账号和密码
User user = validUser(username, password);
//返回Token
return getTokenEntity(user);
}
@Override
public User register(String name, String password) throws Exception {
User user = userRepository.findUserByUsername(name);
SaltAndPassword saltAndPassword = PasswordUtil.mix(password);
if (user == null) {
user = new User();
user.setUsername(name);
user.setPassword(saltAndPassword.getMixedPassword());
user.setSalt(saltAndPassword.getSalt());
return userRepository.save(user);
} else {
throw new Exception("user is existed");
}
}
@Override
public User findUserById(int id) {
return userRepository.findUserById(id);
}
@Override
public User validUser(String name, String password) throws Exception {
User user = userRepository.findUserByUsername(name);
if (user != null) {
String pwd = PasswordUtil.mix(password, user.getSalt());
if (pwd.equals(user.getPassword())) {
return user;
} else {
throw new Exception("password is not correct");
}
} else {
throw new Exception("user is not exist");
}
}
@Override
public String getTokenEntity(User user) {
String token = null;
try {
token = JwtUtil.createToken(user.getId());
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return token;
}
}
controller层
@RestController
public class UserController {
@Autowired
private UserService userService;
@ApiOperation(value = "账号密码登录", httpMethod = "POST", notes = "账号密码登录")
@PostMapping("/login")
public Object login(@RequestBody UserModel model) throws Exception {
HashMap<String, String> result = new HashMap<>();
result.put("token", userService.login(model.getUsername(), model.getPassword()));
return result;
}
@ApiOperation(value = "通过Token获取用户信息", httpMethod = "GET",notes ="通过Token获取用户信息" )
@GetMapping("/getUser")
public User getUser(String token) throws Exception {
Map<String, Claim> map = JwtUtil.verifyToken(token);
Claim claim = map.get("userId");
User user = userService.findUserById(claim.asInt());
return user;
}
@ApiOperation(value = "用户注册", httpMethod = "POST", notes = "用户注册")
@PostMapping("/register")
public User register(@RequestBody UserModel model) throws Exception {
User user = userService.register(model.getUsername(), model.getPassword());
return user;
}
}
测试结果


该博客详细介绍了如何在SpringBoot项目中集成JWT来生成Token,包括创建项目、添加依赖、配置SwaggerUI、application.properties设置、Redis配置、JWT Token生成类的编写、User实体类与密码盐加密处理,以及 Dao、Service、ServiceImpl 和 Controller 层的实现步骤。
1381

被折叠的 条评论
为什么被折叠?



