您的位置:首页技术文章
文章详情页

java - 前后端分离验证码的问题

浏览:26日期:2023-11-11 17:28:33

问题描述

前提

假设我有一个获取验证码的接口它在https://api.b.com/captcha下面。

我想象中的刷新验证码的方式

在我的想象中验证码刷新功能是通过在url后面加上?时间戳实现的,例如把url变成这样子

https://api.b.com/captcha?149...

传统验证验证码的做法

传统的验证码应该主要是通过session来做的吧,前端会在cookie里面记录一个session id。

后端也会在redis里面记录这个session id以及它对应的验证码。

前端有个点击验证码刷新的功能,每次点击都会生成新的验证码,每次都会在redis里面更新这个session id对应的验证码的值。

验证方式是通过查询redis里面的session id得值和前端的值是否一致来完成的。

目前遇到的问题

现在,我在做一个前后端分离的项目。

然后有一个cookie跨域的问题我不知道怎么解决。

场景如下前端项目在 www.a.com的域名下,后端项目在 api.b.com的域名下。

前端和后端是在不同的域名下的(其实把两个项目放在同一个域名下面也是可以的,学习目的就不这么做了),于是cookie无法共享,换而言之我获取不到session id了。那么传统的方式好像就不可以了。

PS: 前端的服务器会用nginx做,后端用的是spring-boot。

我的想法想法一

我想生成一个简单的token,token只包含了一个uuid,用于辨别用户。我通过这个toekn的uuid和redis里面的uuid比对来判断验证码的值是否正确。所以我将会返回一个这样子的结果

{ image : base64转码后的图片, token : uuid}

关于为什么发base64转码后的图片,主要是因为前端的img标签是支持base64的。发这个话直接显示出来没问题(不是一个不考虑古老浏览器的项目)。

但是这样子做,好像也并不太合理。因为这样子访问验证码的地址的时候就不能看见验证码的图片了。不方便调试查看验证码的样式了,其实也不算特别不方便,只是还要特地写个js来设置img的src,感觉挺蠢的。

想法二

把token放到response的header里面。js是读得到response header里面的东西的。然后这样子验证码的图片也可以通过地址直接显示出来。但是特喵的,感觉也很蠢。因为就不能用到我想象中的刷新验证码的方式了。直接简单的在后面添加时间戳就修改的方式。

想法三

验证码我不管了,前端的服务器去做这事情吧,登陆的时候在前端服务器验证验证码,然后我后端只验证账号密码是不是正确的回个token算了。每次访问其他的api带上token就好了。

实在想不到怎么做了,相关资料也没找到(可能是我的搜索方式有问题),所以求各位大佬帮忙....

认真的又查了下这个问题应该是单点登录的问题吧?

问题解答

回答1:

你要解决的是跨域携带cookie的问题。首先要确定你跨域使用的是cors技术,cors可以基于 HTTP cookies 和 HTTP 认证信息发送身份凭证。 通过XMLHttpRequest 的 withCredentials 标志设置为 true,从而向服务器发送 Cookies。

var invocation = new XMLHttpRequest();var url = ’http://bar.other/resources/credentialed-content/’; function callOtherDomain(){ if(invocation) { invocation.open(’GET’, url, true); invocation.withCredentials = true; invocation.onreadystatechange = handler; invocation.send(); }}

除了前端发请求要添加withCredential外,服务器的响应头也需要添加Access-Control-Allow-Credentials: true。另外,响应头不能设置 Access-Control-Allow-Origin 的值为“*”,必须设为具体的源 http://foo.example。

标签: java
相关文章: