1.引入關鍵依賴
<!-- redis --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <!-- spring2.X集成redis所需common-pool2--> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> <version>2.6.0</version> </dependency> <!-- JWT--> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> </dependency>
2.jwt .md5 redis工具類
public class JwtUtils { //常量 public static final long EXPIRE = 1000 * 60 * 60 * 24; //token過期時間 public static final String APP_SECRET = "ukc8BDbRigUDaY6pZFfWus2jZWLPHO"; //秘鑰 //生成token字符串的方法 public static String getJwtToken(String id, String nickname){ String JwtToken = Jwts.builder() .setHeaderParam("typ", "JWT") .setHeaderParam("alg", "HS256") .setSubject("guli-user") .setIssuedAt(new Date()) .setExpiration(new Date(System.currentTimeMillis() + EXPIRE)) .claim("id", id) //設置token主體部分 ,存儲用戶信息 .claim("nickname", nickname) .signWith(SignatureAlgorithm.HS256, APP_SECRET) .compact(); return JwtToken; } /** * 判斷token是否存在與有效 * @param jwtToken * @return */ public static boolean checkToken(String jwtToken) { if(StringUtils.isEmpty(jwtToken)) return false; try { Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken); } catch (Exception e) { e.printStackTrace(); return false; } return true; } /** * 判斷token是否存在與有效 * @param request * @return */ public static boolean checkToken(HttpServletRequest request) { try { String jwtToken = request.getHeader("token"); if(StringUtils.isEmpty(jwtToken)) return false; Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken); } catch (Exception e) { e.printStackTrace(); return false; } return true; } /** * 根據token字符串獲取會員id * @param request * @return */ public static String getMemberIdByJwtToken(HttpServletRequest request) { String jwtToken = request.getHeader("token"); if(StringUtils.isEmpty(jwtToken)) return ""; Jws<Claims> claimsJws = Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken); Claims claims = claimsJws.getBody(); return (String)claims.get("id"); } }
public final class MD5 { public static String encrypt(String strSrc) { try { char hexChars[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; byte[] bytes = strSrc.getBytes(); MessageDigest md = MessageDigest.getInstance("MD5"); md.update(bytes); bytes = md.digest(); int j = bytes.length; char[] chars = new char[j * 2]; int k = 0; for (int i = 0; i < bytes.length; i++) { byte b = bytes[i]; chars[k++] = hexChars[b >>> 4 & 0xf]; chars[k++] = hexChars[b & 0xf]; } return new String(chars); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); throw new RuntimeException("MD5加密出錯!!+" + e); } } public static void main(String[] args) { System.out.println(MD5.encrypt("111111")); } }
@EnableCaching //開啟緩存 @Configuration //配置類 public class RedisConfig extends CachingConfigurerSupport { @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); RedisSerializer<String> redisSerializer = new StringRedisSerializer(); Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); ObjectMapper om = new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(om); template.setConnectionFactory(factory); //key序列化方式 template.setKeySerializer(redisSerializer); //value序列化 template.setValueSerializer(jackson2JsonRedisSerializer); //value hashmap序列化 template.setHashValueSerializer(jackson2JsonRedisSerializer); return template; } @Bean public CacheManager cacheManager(RedisConnectionFactory factory) { RedisSerializer<String> redisSerializer = new StringRedisSerializer(); Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); //解決查詢緩存轉換異常的問題 ObjectMapper om = new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(om); // 配置序列化(解決亂碼的問題),過期時間600秒 RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig() .entryTtl(Duration.ofSeconds(600)) .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer)) .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer)) .disableCachingNullValues(); RedisCacheManager cacheManager = RedisCacheManager.builder(factory) .cacheDefaults(config) .build(); return cacheManager; } }
3.controller層
@RestController @RequestMapping("/educenter/member") @CrossOrigin public class UcenterMemberController { @Autowired private UcenterMemberService memberService; //登錄 @PostMapping("login") public R loginUser(@RequestBody UcenterMember member) { //member對象封裝手機號和密碼 //調用service方法實現登錄 //返回token值,使用jwt生成 String token = memberService.login(member); return R.ok().data("token",token); } //注冊 @PostMapping("register") public R registerUser(@RequestBody RegisterVo registerVo) { memberService.register(registerVo); return R.ok(); } //根據token獲取用戶信息 @GetMapping("getMemberInfo") public R getMemberInfo(HttpServletRequest request) { //調用jwt工具類的方法。根據request對象獲取頭信息,返回用戶id String memberId = JwtUtils.getMemberIdByJwtToken(request); //查詢數據庫根據用戶id獲取用戶信息 UcenterMember member = memberService.getById(memberId); return R.ok().data("userInfo",member); } }
4.service層
@Service public class UcenterMemberServiceImpl extends ServiceImpl<UcenterMemberMapper, UcenterMember> implements UcenterMemberService { @Autowired private RedisTemplate<String,String> redisTemplate; //登錄的方法 @Override public String login(UcenterMember member) { //獲取登錄手機號和密碼 String mobile = member.getMobile(); String password = member.getPassword(); //手機號和密碼非空判斷 if(StringUtils.isEmpty(mobile) || StringUtils.isEmpty(password)) { throw new GuliException(20001,"登錄失敗"); } //判斷手機號是否正確 QueryWrapper<UcenterMember> wrapper = new QueryWrapper<>(); wrapper.eq("mobile",mobile); UcenterMember mobileMember = baseMapper.selectOne(wrapper); //判斷查詢對象是否為空 if(mobileMember == null) {//沒有這個手機號 throw new GuliException(20001,"登錄失敗"); } //判斷密碼 //因為存儲到數據庫密碼肯定加密的 //把輸入的密碼進行加密,再和數據庫密碼進行比較 //加密方式 MD5 if(!MD5.encrypt(password).equals(mobileMember.getPassword())) { throw new GuliException(20001,"登錄失敗"); } //判斷用戶是否禁用 if(mobileMember.getIsDisabled()) { throw new GuliException(20001,"登錄失敗"); } //登錄成功 //生成token字符串,使用jwt工具類 String jwtToken = JwtUtils.getJwtToken(mobileMember.getId(), mobileMember.getNickname()); return jwtToken; } //注冊的方法 @Override public void register(RegisterVo registerVo) { //獲取注冊的數據 String code = registerVo.getCode(); //驗證碼 String mobile = registerVo.getMobile(); //手機號 String nickname = registerVo.getNickname(); //昵稱 String password = registerVo.getPassword(); //密碼 //非空判斷 if(StringUtils.isEmpty(mobile) || StringUtils.isEmpty(password) || StringUtils.isEmpty(code) || StringUtils.isEmpty(nickname)) { throw new GuliException(20001,"注冊失敗"); } //判斷驗證碼 //獲取redis驗證碼 String redisCode = redisTemplate.opsForValue().get(mobile); if(!code.equals(redisCode)) { throw new GuliException(20001,"注冊失敗"); } //判斷手機號是否重復,表里面存在相同手機號不進行添加 QueryWrapper<UcenterMember> wrapper = new QueryWrapper<>(); wrapper.eq("mobile",mobile); Integer count = baseMapper.selectCount(wrapper); if(count > 0) { throw new GuliException(20001,"注冊失敗"); } //數據添加數據庫中 UcenterMember member = new UcenterMember(); member.setMobile(mobile); member.setNickname(nickname); member.setPassword(MD5.encrypt(password));//密碼需要加密的 member.setIsDisabled(false);//用戶不禁用 member.setAvatar("http://thirdwx."); baseMapper.insert(member); } }
5.vo類
@Data public class RegisterVo { @ApiModelProperty(value = "昵稱") private String nickname; @ApiModelProperty(value = "手機號") private String mobile; @ApiModelProperty(value = "密碼") private String password; @ApiModelProperty(value = "驗證碼") private String code; }