vue axios springboot2.0 cookie token jwt 跨域 cors cookie存token header 头请求带token 登陆login 采坑记录
首先
后端
pom文件
io.jsonwebtoken
jjwt
0.9.1
配置类(springboot2.0的环境下直接把这个类粘到项目里面就可以了)
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
//配置类(springboot2.0的环境下直接把这个类粘到项目里面就可以了)
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
//设置允许跨域的路径
registry.addMapping("/**")
//设置允许跨域请求的域名
.allowedOrigins("*")
//是否允许证书 不再默认开启
.allowCredentials(true)
//设置允许的方法
.allowedMethods("*")
//跨域允许时间
.maxAge(3600);
}
}
jwt Token工具类:
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Objects;
public class TokenUtils {
// public static final Key key = MacProvider.generateKey();
//这里直接使用的写死的1234 为 key 这样可以保证每次请求生成的token一致,方便测试
public static final String key = "1234";
/**
* 传入用户名获取token
*
* @param username
* @return
*/
public static String getToken(String username) {
return Jwts.builder()//返回的字符串便是我们的jwt串了
.setSubject(username)//设置主题
.signWith(SignatureAlgorithm.HS256, key)//设置算法(必须)
.compact();//这个是全部设置完成后拼成jwt串的方法
}
/**
* 传入token获取用户名
*
* @param token
* @return
*/
public static String getUsername(String token) {
if (isCorrect(token)) {
return Jwts.parser().setSigningKey(key).parseClaimsJws(token).getBody().getSubject();
}
return "";
}
//判断是否有效token
public static boolean isCorrect(String token) {
return Objects.nonNull(token);
}
}
cookie工具类
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class CookieUtils {
//根据cookie名获取cookie值
public static String getCookie(HttpServletRequest request, String cookieName) {
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
if (cookie.getName().equals(cookieName)) {
return cookie.getValue();
}
}
}
return null;
}
//给请求的返回内容中写入cookie
public static void writeCookie(HttpServletResponse response, String cookieName, String value) {
Cookie cookie = new Cookie(cookieName, value);
cookie.setPath("/");
cookie.setMaxAge(3000 * 60);
response.addCookie(cookie);
}
}
User类:
import java.security.Principal;
public class User implements Principal {
private String name;
/**
* Returns the name of this principal.
*
* @return the name of this principal.
*/
@Override public String getName() {
return this.name;
}
}
登陆controller:
@Controller
@RequestMapping("login")
public class LoginController {
@PostMapping("")
@ResponseBody
public String Login(@RequestBody User user, HttpServletResponse response, HttpServletRequest request,
@CookieValue(value = "token", required = false) String token) {
//可以从cookie和头请求两个地方获取cookie,一般为了防止跨域攻击,需要验证头请求和cookie中的token是否一致,
//cookie的token跨域攻击可以模拟,但头请求中的跨域攻击无法模拟
String headerToken = request.getHeader("token");
System.out.println("headerToken:" + headerToken);
System.out.println("cookieToken:" + token);
if (token == null) {
CookieUtils.writeCookie(response, "token", TokenUtils.getToken(user.getName()));
} else {
String username = TokenUtils.getUsername(token);
if (user.getName().equals(username)) {
return "验证成功!"+username;
}
}
//返回前台
return "第一次登陆或者登录失败";
}
}
前端:
js-cookie是个操作cookie的工具,可以百度下
这里有个坑,就是你浏览器地址栏访问前端项目用的是ip就访问后台的baseURL就要使用ip,
如果你地址栏用的localhost相同baseUrl也要是localhost
axios配置
import Axios from 'axios'
import Cookies from 'js-cookie'
//方便测试,每次刷新页面都清空cookie中的token
Cookies.remove('token');
const axios = Axios.create({
// baseURL: 'http://localhost:8066',
baseURL: 'http://192.168.1.107:8066',
withCredentials:true,
timeout: 5000,
});
axios.interceptors.request.use(
config => {
// 这里写死一个token,你需要在这里取到你设置好的token的值
const token = Cookies.get('token');
console.log(Cookies.get('token'))
console.log(Cookies.get())
console.log(token)
if (token) {
// 这里将token设置到headers中,header的key是token,这个key值根据你的需要进行修改即可
config.headers.token = token;
}
return config
},
error => {
return Promise.reject(error)
});
export default axios
登录页面:
登录