假设我有一个获取验证码的接口它在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就好了。
实在想不到怎么做了,相关资料也没找到(可能是我的搜索方式有问题),所以求各位大佬帮忙....
认真的又查了下这个问题应该是单点登录的问题吧?
代言2017-06-12 09:22:13
你要解决的是跨域携带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。