java - 前后端分离验证码的问题
问题描述
前提假设我有一个获取验证码的接口它在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。
相关文章:
1. mac OSX10.12.4 (16E195)下Mysql 5.7.18找不到配置文件my.cnf2. mysql - 怎么生成这个sql表?3. mysql储存json错误4. php - 公众号文章底部的小程序二维码如何统计?5. mysql - 表名称前缀到底有啥用?6. mysql - 数据库表中,两个表互为外键参考如何解决7. Navicat for mysql 中以json格式储存的数据存在大量反斜杠,如何去除?8. 在mybatis使用mysql的ON DUPLICATE KEY UPDATE语法实现存在即更新应该使用哪个标签?9. mysql - 数据库建字段,默认值空和empty string有什么区别 11010. sql语句 - 如何在mysql中批量添加用户?
