前言

最近的新项目中,用户登录需要采用cookie来记住用户,校验身份。所以本文就把实现的过程总结出来分享给大家,需要的朋友们可以参考学习。
在header中携带authId登录
在之前老的项目里,没有采用cookie来记录用户登录状态,而是在请求的header中携带一个身份标识来校验,大致方案如下:
上面的方案,如果其他客户端知道了这个authId后,可以在其他客户端模拟身份,不安全,因此弃用。
用cookie记住用户
新项目中,将采用此文即将介绍的方案–利用cookie来记住用户。主要流程是:
整个过程可以用下面这张图简单表示:
前台用angular搭建单页客户端应用,后台用node搭建服务器,数据存放在mongodb中,这三个技术及cookie基础知识本文不做介绍,感兴趣的同学可以自行了解。
以下的代码都是最简单的get/post请求,但也是最核心的部分,其他有关登录的繁琐操作,感兴趣的同学可以自行补充。
从开始–>结束,遇到的问题
首先,我用的是最基础的post请求,服务端也只是简单的返回数据,部分简单但比较核心的代码如下:
// client
$http({
method : 'POST',
url : 'http://127.0.0.1:8888/rest/user',
data : {name: 'xxx',password:'***'}
}).success(function (data) {
console.log('login success,data is:'+data);
}).error(function (data) {
console.log('login error');
}).then(function () {
console.log(arguments);
});
// server
var cookie = "authId=" + authId;
res.setHeader('Content-Type', 'application/json;charset=utf-8');
res.setHeader('Set-Cookie', cookie + ';Max-Age=3600;HttpOnly=false;Path=/;');
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end();
查看chrome调试,发现虽然服务端的cookie推过来了,但整体出了问题,提示如下:
XMLHttpRequest cannot load http://127.0.0.1:8888/rest/user. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:62427' is therefore not allowed access.
分析问题后,发现原因是来自客户端的请求不能跨域访问服务端的请求,请求的资源header中没有携带允许跨越请求的信息。根据这个提示,我们把服务端的代码稍加改进后,如下:
// server
var cookie = "authId=" + authId;
res.setHeader('Content-Type', 'application/json;charset=utf-8');
res.setHeader('Set-Cookie', cookie + ';Max-Age=3600;HttpOnly=false;Path=/;');
// 添加允许跨越的头信息
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end();
解释下上面代码什么意思,第一句主要是允许来自任何域的请求访问,第二句是允许哪些类型的请求访问。加上后再次运行,提示如下:
XMLHttpRequest
cannot load http://127.0.0.1:8888/rest/user. Request header field Content-Type is not allowed by Access-Control-Allow-Headers in preflight response.
原因是来自客户端的请求中,Content-Type头字段,在服务端的响应信息的头中,没有携带,再次修改代码如下:
// server
var cookie = "authId=" + authId;
res.setHeader('Content-Type', 'application/json;charset=utf-8');
res.setHeader('Set-Cookie', cookie + ';Max-Age=3600;HttpOnly=false;Path=/;');
// 添加允许跨越的头信息
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
// 添加支持Content-Type允许的头信息
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end();
再次运行代码,发现没有错误提示,但是当我们再次请求服务器时,发现客户端的请求并没有携带cookie信息,这显然不是我们想要的效果:
在查阅了一段时间后了解到,客户端是会默认携带cookie给服务端的,但是当客户端的请求是跨域请求时,由于跨域请求本身就有风险,而携带给cookie同样有风险。
因此在进行跨域访问时,客户端不会将服务端返回的cookie携带。此时,我们需要同时在客户端和服务端都设置“withCredentials”为true,代码如下:
// client
$http({
method : 'POST',
url : 'http://127.0.0.1:8888/rest/user',
withCredentials: true
data : {name: 'xxx',password:'***'}
}).success(function (data) {
console.log('login success,data is:'+data);
}).error(function (data) {
console.log('login error');
}).then(function () {
console.log(arguments);
});
// server
var cookie = "authId=" + authId;
res.setHeader('Content-Type', 'application/json;charset=utf-8');
res.setHeader('Set-Cookie', cookie + ';Max-Age=3600;HttpOnly=false;Path=/;');
// 添加允许跨越的头信息
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
// 添加支持Content-Type允许的头信息
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
// 设置已携带凭证为true
//res.setHeader('Access-Control-Allow-Credentials', true);
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end();
运行后,发现又有错误提示,如下:
XMLHttpRequest cannot load http://127.0.0.1:8888/rest/user. Response to preflight request doesn't pass access control check: A wildcard '*' cannot be used in the 'Access-Control-Allow-Origin' header when the credentials flag is true. Origin 'http://localhost:62427' is therefore not allowed access.
分析错误后发现,原因是当设置了已携带凭证参数为true时,允许跨域请求的源不能设置为泛型的“*”,因此我们再次修改代码如下:(最终代码)
// client
$http({
method : 'POST',
url : 'http://127.0.0.1:8888/rest/user',
withCredentials: true
data : {name: 'xxx',password:'***'}
}).success(function (data) {
console.log('login success,data is:'+data);
}).error(function (data) {
console.log('login error');
}).then(function () {
console.log(arguments);
});
// server
var cookie = "authId=" + authId;
res.setHeader('Content-Type', 'application/json;charset=utf-8');
res.setHeader('Set-Cookie', cookie + ';Max-Age=3600;HttpOnly=false;Path=/;');
// 添加允许跨越的头信息
// res.setHeader('Access-Control-Allow-Origin', '*');
// 用当前的客户端origin来取代泛型的“*”
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:62427');
res.setHeader('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
// 添加支持Content-Type允许的头信息
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
// 设置已携带凭证为true
res.setHeader('Access-Control-Allow-Credentials', true);
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end();
此时,第一次请求服务端时,服务端返回cookie信息,以后每次客户端请求服务端,客户端的header中都会携带cookie信息,效果如下图:
最后
以上就是在使用cookie记住用户身份时遇到的一些问题及简单解决方法,一般在angular应用中,可能使用较多的是resoure进行http通信,此时只要在GET/POST/PUT/DELETE等请求的参数中,将“withCredentials”设置为true即可。希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。
# angularjs
# 操作cookie
# angular
# cookie
# 用法
# nodejs
# 登录
# js实现登录注册框手机号和验证码校验(前端部分)
# JavaScript 完成注册页面表单校验的实例
# JavaScript注册时密码强度校验代码
# js简单实现用户注册信息的校验代码
# JS校验与最终登陆界面功能完整示例
# 详解AngularJs HTTP响应拦截器实现登陆、权限校验
# jsp登陆校验演示 servlet、login、success
# 拦截JSP页面
# 校验是否已登录详解及实现代码
# ASP.NET MVC结合JavaScript登录、校验和加密
# javascript使用正则表达式实现注册登入校验
# 服务端
# 客户端
# 的是
# 感兴趣
# 是否合法
# 设置为
# 用户登录
# 可以自行
# 错误提示
# 都是
# 是在
# 放在
# 出了
# 一句
# 就有
# 可以用
# 又有
# 朋友们
# 我用
# 就把
相关文章:
javascript中的try catch异常捕获机制用法分析
魔方云NAT建站如何实现端口转发?
如何在IIS中新建站点并配置端口与IP地址?
购物网站制作公司有哪些,哪个购物网站比较好?
如何高效利用亚马逊云主机搭建企业网站?
定制建站如何定义?其核心优势是什么?
网站制作的软件有哪些,制作微信公众号除了秀米还有哪些比较好用的平台?
如何制作算命网站,怎么注册算命网站?
太平洋网站制作公司,网络用语太平洋是什么意思?
公司门户网站制作公司有哪些,怎样使用wordpress制作一个企业网站?
如何快速配置高效服务器建站软件?
赚钱网站制作软件,建一个网站怎样才能赚钱?是如何盈利的?
如何在香港服务器上快速搭建免备案网站?
如何在万网开始建站?分步指南解析
香港服务器建站指南:免备案优势与SEO优化技巧全解析
如何在万网自助建站平台快速创建网站?
Bpmn 2.0的XML文件怎么画流程图
唐山网站制作公司有哪些,唐山找工作哪个网站最靠谱?
长沙做网站要多少钱,长沙国安网络怎么样?
小说建站VPS选用指南:性能对比、配置优化与建站方案解析
成都品牌网站制作公司,成都营业执照年报网上怎么办理?
建站之星如何实现五合一智能建站与营销推广?
如何在Golang中使用replace替换模块_指定本地或远程路径
如何正确下载安装西数主机建站助手?
长沙企业网站制作哪家好,长沙水业集团官方网站?
建站主机核心功能解析:服务器选择与网站搭建流程指南
网站制作报价单模板图片,小松挖机官方网站报价?
简单实现Android验证码
阿里云高弹*务器配置方案|支持分布式架构与多节点部署
如何在阿里云ECS服务器部署织梦CMS网站?
C++时间戳转换成日期时间的步骤和示例代码
如何在阿里云虚拟主机上快速搭建个人网站?
香港服务器网站搭建教程-电商部署、配置优化与安全稳定指南
建站10G流量真的够用吗?如何应对访问高峰?
如何将凡科建站内容保存为本地文件?
深入理解Android中的xmlns:tools属性
如何用AWS免费套餐快速搭建高效网站?
如何在阿里云部署织梦网站?
网站制作服务平台,有什么网站可以发布本地服务信息?
公司网站的制作公司,企业网站制作基本流程有哪些?
如何用花生壳三步快速搭建专属网站?
高防网站服务器:DDoS防御与BGP线路的AI智能防护方案
c++怎么实现高并发下的无锁队列_c++ std::atomic原子变量与CAS操作【详解】
宝盒自助建站智能生成技巧:SEO优化与关键词设置指南
如何做静态网页,sublimetext3.0制作静态网页?
建站之星安装后如何配置SEO及设计样式?
道歉网站制作流程,世纪佳缘致歉小吴事件,相亲网站身份信息伪造该如何稽查?
,网站推广常用方法?
建站之星如何助力企业快速打造五合一网站?
宝塔Windows建站如何避免显示默认IIS页面?
*请认真填写需求信息,我们会在24小时内与您取得联系。