springSecurity:
导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
配置类,springSecurity只用来做加密解密,设为所有路径放行
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/**").permitAll()
.anyRequest().authenticated()
.and().csrf().disable();
}
}
注册发送验证码,根据手机号作为相关标识key存入redis
public void getCode(String mobile) {
String checkCode= RandomCode.getRandomCode();
redisUtils.set("checkCode_"+mobile,checkCode,3*60);
Map<String,String> map =new HashMap<>();
map.put("checkCode",checkCode);
map.put("mobile",mobile);
rabbitTemplate.convertAndSend("sms",map);
}
另外一边rabbitmq监听到sms队列,发送阿里云验证码短信,代码就不贴了。
得到验证码后注册
public void register(String mobile,String code,String userName,String password) {
System.out.println(redisUtils.get("checkCode_"+mobile));
if(code.equals(redisUtils.get("checkCode_"+mobile))){
String pwdlock=bCryptPasswordEncoder.encode(password);
User u=new User();
u.setUserPassword(pwdlock);
u.setUserName(userName);
userDao.insert(u);
System.out.println("注册成功!");
}
else{
System.out.println("注册失败");
}
}
jwt:
导入依赖
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.6.0</version>
</dependency>
jwt
登录
@GetMapping("/login")
public String login() {
User u = new User();
u.setUserName("gkl");
u.setUserPassword("123456");
userService.login(u);
//admin这里为角色,开发环境去数据库查,这里就写死了
String token = jwtUtil.createJWT("gkl", "gkl", "admin");
System.out.println(token);
return token;
}
public User login(User u) {
User user=userDao.selectByUserName(u.getUserName());
if(user!=null&&bCryptPasswordEncoder.matches(u.getUserPassword(),user.getUserPassword())){
System.out.println("登录成功!");
return user;
}
System.out.println("登录失败!");
return null;
}
jwt配置类
package com.gkl1120.mybatisplus.jwt;
import com.gkl1120.mybatisplus.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.WebMvcConfigurationSupport;
@Configuration
public class JWTConfig extends WebMvcConfigurationSupport {
@Autowired
private JwtInterceptor jwtInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(jwtInterceptor).
addPathPatterns("/**").
excludePathPatterns("/**/login/**");
}
}
根据业务所需写jwt拦截器
package com.gkl1120.mybatisplus.interceptor;
import com.gkl1120.mybatisplus.jwt.JwtUtil;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @author ctx_gao kailong
* @date 2020/4/7 12:14
*/
@Component
public class JwtInterceptor extends HandlerInterceptorAdapter {
@Autowired
private JwtUtil jwtUtil;
//拦截器只作解析token的作用,没有携带头参数Authorization照样放行
// public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// System.out.println("经过了拦截器!");
// final String authHeader = request.getHeader("Authorization");
// if (authHeader != null && authHeader.startsWith("auth ")) {
// final String token = authHeader.substring(5); // The part after "auth "
// Claims claims = null;
// try {
// claims = jwtUtil.parseJWT(token);
// } catch (Exception e) {
// throw new Exception("token异常!");
// }
// if (claims != null) {
// if("admin".equals(claims.get("roles"))){//如果是管理员
// request.setAttribute("admin_claims", claims);
// }
// if("user".equals(claims.get("roles"))){//如果是用户
// request.setAttribute("user_claims", claims);
// }
// }
// }
// return true;
// }
//每个方法都验证token
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("经过了拦截器!");
final String authHeader = request.getHeader("Authorization");
if (authHeader == null || !authHeader.startsWith("auth ")) {
throw new Exception("无token!");
}
final String token = authHeader.substring(5); // The part after "auth "
Claims claims = null;
try {
claims = jwtUtil.parseJWT(token);
} catch (Exception e) {
throw new Exception("token异常!");
}
if (claims != null) {
if("admin".equals(claims.get("roles"))){//如果是管理员
request.setAttribute("admin_claims", claims);
}
if("user".equals(claims.get("roles"))){//如果是用户
request.setAttribute("user_claims", claims);
}
}
return true;
}
}
jwt工具类,创建或解析token
package com.gkl1120.mybatisplus.jwt;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import java.util.Date;
@Configuration
@ConfigurationProperties("jwt.config")
public class JwtUtil {
private String key;
private long ttl;
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public long getTtl() {
return ttl;
}
public void setTtl(long ttl) {
this.ttl = ttl;
}
/**
* 生成JWT
*
* @param id
* @param subject
* @return
*/
public String createJWT(String id, String subject, String roles) {
long nowMillis = System.currentTimeMillis();
Date now = new Date(nowMillis);
JwtBuilder builder = Jwts.builder().setId(id)
.setSubject(subject)
.setIssuedAt(now)
.signWith(SignatureAlgorithm.HS256, key).claim("roles",
roles);
if (ttl > 0) {
builder.setExpiration(new Date(nowMillis + ttl));
}
return builder.compact();
}
public String createJWT(String subject) {
long nowMillis = System.currentTimeMillis();
Date now = new Date(nowMillis);
JwtBuilder builder = Jwts.builder()
.setSubject(subject)
.setIssuedAt(now)
.signWith(SignatureAlgorithm.HS256, key);
if (ttl > 0) {
builder.setExpiration(new Date(nowMillis + ttl));
}
return builder.compact();
}
/**
* 解析JWT
*
* @param jwtStr
* @return
*/
public Claims parseJWT(String jwtStr) {
return Jwts.parser()
.setSigningKey(key)
.parseClaimsJws(jwtStr)
.getBody();
}
}
配置文件加上盐
jwt.config.key=gkl1120
jwt.config.ttl=60000
现在就可以根据角色的不同控制接口访问权限,例如这个list只能admin查:
@Autowired
private RedisUtils redisUtils;
@Autowired
private JwtUtil jwtUtil;
@Autowired
private HttpServletRequest request;
@Autowired
private UserService userService;
@RequestMapping("/list")
public Object list() {
if(request.getAttribute("admin_claims")==null){
System.out.println("权限不足");
return "权限不足!";
}
if(redisUtils.hasKey("user/list")) {
System.out.println("到缓存取");
System.out.println(redisUtils.get("user/list"));
return redisUtils.get("user/list");
}
else{
List<User> users = userDao.selectAllUser();
System.out.println("从数据库取");
System.out.println(users);
redisUtils.set("user/list",users);
return users;
}
}