基于security的前后端分离项目尝试踩坑和解决实录
到访游客请注意,如果你有相似的问题,请不要跟着步骤,这里记录的是踩坑和解决
解决在最后:debug不如rebuild:)
开始踩坑
坑1:首先是数据库设计
很自然的想到用户登录是一个表。
用户需要权限角色,可能一对多,所以出现了角色表。
这些接口有哪些角色可以使用。
出现第一个大坑。
security的接口权限设计是这样的:在服务器第一次启动的时候会为这些接口设置权限角色
也就是
权限角色
.hasAnyAuthority
还一个用来给用户分配的角色
用户角色
.hasAnyRole()
实际上security的架构需要四层数据表
如果只有三层,一般只能选择将权限角色和用户角色合并
但security的架构原因会锁死,接口开放给哪些权限角色
会让服务只能管理用户拥有哪些角色
不能管理角色拥有哪些权限接口
坑2:security的函数式编程设置是有顺序的
这个坑十分的魔幻
经过多次尝试得出标题结论
不按照顺序进行设置总是不能达到逻辑上希望实现的效果
详细的路径放前面,通配的路径放后面
/root/abc----->>>>/root/**
/root/**----- >>>>/**
前面的路径权限会覆盖后面的路径权限,逻辑通顺
其他的都会出现不可名状的错误。
因为坑1导致的坑3
因为坑一写死了权限角色,权限角色和用户角色合并
这导致了维护灾难
当新的接口出现的时候!!!
这个接口属于哪个角色?
这个权限给这个角色是否合理?
是否需要新增一个角色?
新增角色分配用户该怎么分配?
这些问题竟然需要提前想好!!!
而不是用到再去新增
坑4:后端跨域问题
因为是前后端分离的项目,前端9090访问后端8080。
前端直接喜提cors报错
然后学习security该怎么处理跨域加个.cors();
还有拓展知识等着你来。
1.既然前后端分离那怎么保证session
security使用往前端的cookie里塞sessionID
请求的时候再用sessionid来获得服务器上准备的session
2.既然是session那关闭浏览器再开启会失效,是怎么实现的。
3.二的问题该怎么用token来解决
这个还没学
坑4.5登录问题
security默认是8080/login返回一个默认的login.html
前端直接请求会返回一串html而不是想要的验证cookie的SessionId
所以需要配置security来自定义登录界面。
好在只用处理登录逻辑就行了。
我们可以用自带的/login来作为接口
虽然不知道为什么但是登出的逻辑好像要写在登入前面。
坑5前端跨域问题
经过大佬博客指点,终于解决了坑1,2,3,4等。
完成了后端的配置,但是前端还得自己完成。
9090访问8080是没问题了!
现在问题是8080给9090的参数,9090不认。
坑5.1编译器是否有问题
因为是用idea来debug的项目63342,所以我怀疑是开服不规范的问题,而且我找不到idea的debug服务器的配置在哪配置。
然后我掏出了我的node.js来经过一番折腾终于把跨域问题解决了。
坑6:天坑:知识盲区:AJAX的post不能setcookie
经过前面的5坑,明明相应头里面包含一个http-only的cookie但为什么浏览器不会自动帮忙写入。
开始我以为是服务器的问题实际不是,所以省略服务器踩坑。
实际是AJAX就不是干这个的
ajax只有向服务器发送请求时带上cookie的功能可选。
不存在ajax向服务器get的时候带回来cookie的功能。
坑6:解决
把ajax代码改成原本的js代码来完成需求:
悲剧的ajax
$(document).ready(function() {
$('.form-signin').submit(function(event) {
event.preventDefault(); // 阻止表单默认的提交行为
var form = $(this);
var url = form.attr('action');
var formData = form.serialize();
$.ajax({
type: 'POST',
url: 'http://localhost:8080/login',
data: formData,
success: function(response, status, xhr) {
console.log(response)
console.log(status)
console.log(xhr)
var setCookieHeader = xhr.getResponseHeader('Set-Cookie');
if (setCookieHeader) {
var cookies = setCookieHeader.split(';');
for (var i = 0; i < cookies.length; i++) {
document.cookie = cookies[i];
}
}
// 跳转到主页
// $(location).attr('href', 'http://localhost:63342/attendance/managView/index.html');
},
error: function(xhr, status, error) {
// 处理请求错误的情况
}
});
});
});
正确的js
document.addEventListener('DOMContentLoaded', function() {
document.querySelector('.form-signin').addEventListener('submit', function(event) {
event.preventDefault(); // 阻止表单默认的提交行为
var form = this;
var url = form.getAttribute('action');
var formData = new FormData(form);
var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://localhost:8080/login', true);
xhr.withCredentials = true; // 允许发送跨域Cookie
xhr.onload = function() {
if (xhr.status === 200) {
console.log(xhr.responseText);
console.log(xhr.status);
var setCookieHeader = xhr.getResponseHeader('Set-Cookie');
if (setCookieHeader) {
var cookies = setCookieHeader.split(';');
for (var i = 0; i < cookies.length; i++) {
document.cookie = cookies[i];
}
}
// 跳转到主页
// window.location.href = 'http://localhost:63342/attendance/managView/index.html';
} else {
// 处理请求错误的情况
}
};
xhr.onerror = function() {
// 处理请求错误的情况
};
xhr.send(formData);
});
});
正常构建步骤
首先奉上大佬的文章地址,以下内容后端部分全部基于该文章总结。
https://blog.csdn.net/I_am_Hutengfei/article/details/100561564
亲切的大佬的可直接下载的源码
https://github.com/18061495586/Spring-Security-Demo