HTTP是无状态的,一次请求结束,连接断开,下次服务器再收到请求,它就不知道这个请求是哪个用户发过来的。当然它知道是哪个客户端地址发过来的,但是对于我们的应用来说,我们是靠用户来管理,而不是靠客户端。所以对我们的应用而言,它是需要有状态管理的,以便服务端能够准确的知道http请求是哪个用户发起的,从而判断该用户是否有权限继续这个请求。这个过程就是常说的会话管理。
登录的基本流程
目前大多数Web应用采用前后端分离方式进行开发。所以前端网站或应用都属于SPA(Single Page Application)。如果前端,后台API部署在同域下,不存在跨域的情况,登录方式相对简单。
服务器端使用Session技术,浏览器端使用Cookie技术。
基于Token登录,而且可以用于第三方单点登录的OAuth2.0更适合。可以参考网址:理解OAuth 2.0
token传入示例:
简单地说,cookie 就是浏览器储存在用户电脑上的一小段文本文件。cookie 是纯文本格式,不包含任何可执行的代码。一个 Web 页面或服务器告知浏览器按照一定规范来储存这些信息,并在随后的请求中将这些信息发送至服务器,Web 服务器就可以使用这些信息来识别不同的用户。大多数需要登录的网站在用户验证成功之后都会设置一个 cookie,只要这个 cookie 存在并可以,用户就可以自由浏览这个网站的任意页面。再次说明,cookie 只包含数据,就其本身而言并不有害。
同域情况下,Cookie会在随后的请求中携带
跨越定义 :由于浏览器同源策略,凡是发送请求的url的协议(http和https)、域名(www.example.com,about.example.com)、端口(8010和8020)三者之间任意一个与当前页面地址不同则视为跨域。
基于Session和Token登录都要解决。
如果使用同域的方法,那么浏览器会抛出如下错误。demo示例,前端运行在http://localhost:8010/login.html
,后台运行在http://localhost:8020/api/login.php
需要在服务器端设置Header
,以PHP为例:
header('Access-Control-Allow-Origin: http://localhost:8010');
设置完成之后,可以发送请求了,登录成功之后跳转到home.html
还是显示未登录,会跳转到login.html
页面。效果如下图:
基于Session登录才需要,因为相关信息是通过Cookie传入,如果是通过url传入,也不需要解决这个。基于Token,后续请求携带token都是通过header里面的字段,所以也不需要解决这个。
跨越情况下,浏览器此时不会默认在后续请求里面携带上Cookie
信息,这个时候前后端都需要设置。以jQuery
和PHP
为列。
前端jQuery
代码
Ajax请求中药设置xhrFields
xhrFields: {
withCredentials: true
}
完整代码如下:
$.ajax({
url: "http://localhost:8020/api/login.php",
type: "POST",
data: {
username: $("#username").val(),
password: $("#password").val()
},
dataType: "json",
xhrFields: {
withCredentials: true
}
}).done(function (response) {
debugger;
$("#log").html(response.message);
window.location.href = "home.html";
}).fail(function (jqXHR, textStatus) {
console.log("Request failed: " + textStatus);
});
后端php
代码
/*需要设置这一行,接收传入Credentials字段*/
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Allow-Origin: http://localhost:8010');
Demo代码下载:https://share.weiyun.com/5Nm46eU