场景概述
设想一个企业级应用,用户可能在应用的任何页面点击登录,系统需记住用户当前所在位置,并在登录验证通过后自动跳转回该页面。这一过程涉及前端页面与后端服务的紧密配合,以及跨页面状态的维护。
流程梳理
- 前端页面初始化
○ 用户在任一页面操作触发登录需求。 - 捕获当前路径
○ 使用Vue Router或window.location.href获取当前页面URL。 - 发起预登录请求
○ 通过axios或Fetch API向后端发送一个GET请求到/api/web/login-url,携带当前页面URL作为callbackUrl参数。 - 后端处理登录前请求
○ 后端接收callbackUrl,存储于session中。
○ 生成登录页面URL,并携带callbackUrl作为参数。
○ 发送重定向指令,使用户浏览器跳转至登录页面。 - 用户登录操作
○ 用户在登录页面输入用户名和密码并提交表单。 - 后端验证登录信息
○ 处理登录POST请求,验证用户名和密码。
○ 成功后生成token,并存储必要的用户会话信息。 - 重定向回原页面
○ 从session中取出之前存储的callbackUrl。
○ 使用response.sendRedirect(callbackUrl)将用户重定向回登录前的页面。
○ 如果没有有效的callbackUrl,则重定向至默认首页。
Step1 前端处理:携带当前路径
关键技术点:
● 捕获当前路径:利用Vue框架的vue-router或直接从window.location.href获取当前页面URL。
● 异步请求传递信息:通过Ajax(或Fetch API)向后端发送登录前的请求,请求中包含当前页面的URL作为回调地址(callbackUrl)。
示例代码回顾:
async function redirectToLoginPage() {
const currentPath = window.location.href;
try {
await axios.get('/api/web/login-url', {
params: {
callbackUrl: currentPath,
},
});
} catch (error) {
console.error('Failed to get login URL:', error);
}
}
Step2 后端处理:获取登录界面
关键技术点:
● 接收回调URL:后端接口接收前端传来的callbackUrl,并存储于session中(或根据业务需求选择合适的方式)。
● 生成登录URL并重定向:根据业务逻辑生成登录页面的URL,并携带必要的参数(如回调地址),然后重定向用户到该登录页面。
示例代码回顾:
@PostMapping("/api/login-url")
public void generateLoginUrl(HttpServletRequest request, HttpServletResponse response, @RequestParam String callbackUrl) throws IOException {
String loginUrl = "https://your-login-service.com/login?callback=" + callbackUrl;
if (StringUtils.isNotBlank(callbackUrl)) {
request.getSession().setAttribute(CALLBACK_URL_KEY, callbackUrl);
}
response.sendRedirect(loginUrl);
}
Step3 后端处理:登录验证与回调
一旦用户在登录页面输入凭据并提交,后端进行验证,并在验证成功后,根据之前存储的callbackUrl进行重定向,确保用户回到登录前的页面。
关键技术点:
● 登录验证:后端实现逻辑处理用户登录请求,包括账号密码验证、单点登录处理等。
● 重定向逻辑:验证通过后,根据session中保存的callbackUrl或默认首页地址重定向用户。
示例代码回顾:
@PermitAll
@PostMapping("/login")
public void login(HttpServletRequest request, HttpServletResponse response,@RequestBody SelfLoginBody loginBody) throws IOException {
String token = selfLoginService.login(xxx);
final Cookie cookie = new Cookie(homeTokenKey, token);
cookie.setPath("/");
response.addCookie(cookie);
Object attribute = request.getSession().getAttribute(CALLBACK_URL_KEY);
String defaultCallbackUrl = "";
String callbackUrl = attribute != null ? (String) attribute : defaultCallbackUrl;
System.out.println("callbackUrl:" + callbackUrl);
response.sendRedirect(callbackUrl);
}
总结与优化建议
通过上述流程,我们实现了从用户点击登录到成功登录并返回原页面的无缝体验。为了进一步提升体验和安全性,可以考虑以下几点:
● 优化用户体验:增加登录状态的即时反馈,如加载指示器,减少用户等待焦虑。
● 安全性加固:对callbackUrl进行校验,防止开放重定向攻击,确保只重定向到应用内页面。
● 跨域处理:如果前后端部署在不同域名下,需正确配置CORS策略,允许跨域请求。
● 状态管理:考虑使用更现代的状态管理方案(如Redux、Vuex),统一管理登录状态,提高代码可维护性。