前后端分离:WebAPI+Vue开发——远程数据请求axios
前后端分离:WebAPI+Vue开发——跨域设置
前后端分离:WebAPI+Vue开发——身份认证
存储用户身份可以用Cache内存或者Redis,本文实现用的是Redis。
1、在登录页或者首页页面打开后,先获取Token用户身份
在首页或者登录页加载完成后,远程请求服务端,获取服务端生成的token,本文的Token用guid生成,服务端实现如下:
/// <summary>
/// 获取token
/// </summary>
/// <returns></returns>
[HttpGet]
public object GetToken()
{
try
{
Result result = new Result();
result.ret = 1;
var req = Request.Headers.GetValues("token");
string token = req.FirstOrDefault();
if (!string.IsNullOrEmpty(token))//已存在token
{
string key = "user:" + token;
if (RedisHelper.KeyExists(key))//表示用户是登录状态
{
result.ret = 2;
}
}
else
{
token = Guid.NewGuid().ToString();
}
result.data = token;
return result;
}
catch (Exception ex)
{
return ex.Message;
}
}
2、客户端添加验证
客户端获取token值并存储本地cookie,并设置1个小时的有效期,之后页面加载时都判断是否存在token,存在则更新cookie的有效期,不存在则跳转到首页,然后在首页获取token。上面的操作最好是放在一个js公共文件中,在每个页面都引用,涉及到敏感信息的远程请求时,都在请求 头中携带这个token。
JS代码如下:
//用户登录状态检查,未登录转首页
var token = getCookie('token');
if (!token && location.href != 'http://www.abc.com/') {
location.href = '/';
}
if(token){
setCookie('token', token, 60 * 60);
}
3、在服务端存储用户身份信息
用户进行登录操作时,将token数据也发送到服务端,用户登录成功后,以token以键,把用户信息存储在Cache内存或者Redis中,同时设置用户信息的有效期,注意:redis中数据的有效期要与客户端cookie的有效期同步或者时间略长。登录验证码的功能此处不再实现
/// <summary>
/// 登录接口
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
[HttpPost]
public object Login(dynamic data)
{
var req = Request.Headers.GetValues("token");
try
{
Result result = new Result();
string token = req.FirstOrDefault();
string name = Convert.ToString(data.name);
string pwd = Convert.ToString(data.pwd);
Entities db = new Entities();
var userinfo = db.UserInfo.Where(u => u.UserName == name.Trim()).FirstOrDefault();
if (userinfo != null && userinfo.Id > 0)//存在该用户
{
if (userinfo.UserPwd == pwd.Trim())//登录成功
{
string user_key = "user:" + token;
RedisHelper.String_set(user_key, JsonConvert.SerializeObject(userinfo), 60 * 60);//将用户信息存储在redis里边
result.ret = 1;
}
else
{
result.ret = 5;
result.msg = "密码输入错误,请仔细核对";
}
}
else
{
result.ret = 4;
result.msg = "该用户不存在,请检查用户名";
}
return result;
}
catch (Exception ex)
{
return new Result
{
ret = -1,
msg = ex.Message,
data = ""
};
}
}
4、服务端验证Token的有效性
之后的请求,涉及到数据的操作时,每次请求都需要验证请求的合法性,即验证Token的有效性。在WebAPI中,添加一个基类BaseController,需要验证用户身份的Controller都继承基类,在基类中添加Http请求的Header验证,如果header中存在token,并且redis中也有该token的用户信息,则进行后续操作,如果不存在,返回错误状态,前端跳转重新登录的页面。
基类BaseController如下:
public class BaseController : ApiController
{
public string token = "";
public UserInfo user = null;
protected override void Initialize(HttpControllerContext controllerContext)
{
//初始化请求上下文
base.Initialize(controllerContext);
var req = Request.Headers.GetValues("token");
token = req.FirstOrDefault();
if (!string.IsNullOrEmpty(token))
{
string user_key = "user:" + token;
if (Common.RedisHelper.KeyExists(user_key))//判断redis中是否存储的有该用户的信息
{
string json = Common.RedisHelper.String_get(user_key);
user = JsonConvert.DeserializeObject<UserInfo>(json);//反序列化UserInfo
Common.RedisHelper.ExpireKey(user_key, 60 * 60);//更新redis中用户信息的过期时间
}
}
}
}