asp.net core版本:5.0
客户端:Vue
首先我们看一下服务端代码,在startup类的ConfigureServices函数中添加cookie认证:
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie();
这里没有对cookie做任何的设置,如果你想对cookie做一些设置的做,可以这样写:
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(option =>
{
option.Cookie.Name = "MyCookie";
});
其他的对cookie的配置都在CookieAuthenticationOptions这个对象中,大家可以转到这个对象的定义,就可以看到有哪些配置。
CookieAuthenticationDefaults.AuthenticationScheme,这个参数其实就是一个字符串:Cookies,告诉服务器采用哪种认证方案。
其他常用的认证方案还有Jwt(Bearer):JwtBearerDefaults.AuthenticationScheme
不过采用Jwt认证需要安装相应的包,而Cookie认证是ASP.NET CORE自带的认证方式。
在Configure函数中使用认证管道:
app.UseAuthentication();
下面我们写一个登录的函数:
[HttpGet]
public IActionResult Login(string userName, string password)
{
if (userName == "admin" && password == "123456")
{
var claims = new[]
{
new Claim("UserName", userName)
};
var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
var user = new ClaimsPrincipal(claimsIdentity);
HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, user);
return new ObjectResult("登录成功");
}
else
{
return new ObjectResult("用户名或密码不正确");
}
}
没有接触过cookie认证的可能对其中的几个类不太熟悉:Claim、ClaimsIdentity、ClaimsPrincipal。Claim类是声明Cookie的荷载(payload),就是你想在cookie中存放什么内容。
因为Cookie是存储在客户端浏览器中的,所以Cookie的荷载最好不要存储一些比较敏感重要的信息,因为虽然Cookie是经过加密的,但是还是可以被破解。
最后调用SignInAsync函数将声明注册到认证方案,后面每次接收到客户端发送过来的请求时,服务器都会比较注册时的cookie值和客户端发送过来的cookie值,如果相同则认证成功;如果不同则认证失败。
服务器端的代码到这里就写完了,下面看一下vue客户端。
客户端发送登录请求我用的是axios,这里特别要注意的一点是设置axios向服务器发送请求的时候要携带凭证,代码如下:
import axios from 'axios'
axios.defaults.withCredentials = true
使用cookie认证方案的时候就是要把cookie的值放在请求头里面发送给服务器。
客户端的登录代码:
<template>
<div>
<textarea id="username" placeholder="请输入用户名" v-model="loginusername"></textarea>
<textarea id='pwd' placeholder="请输入密码" v-model="loginpassword"></textarea>
<button @click="login">登录</button>
</div>
</template>
<script>
export default {
data: function () {
return {
return: {
loginusername: '',
loginpassword: ''
}
}
},
methods: {
login () {
let username = this.loginusername
let pwd = this.loginpassword
let uri = `http://localhost:5000/api/login/login?userName=${username}&password=${pwd}`
this.axios({
url: uri,
method: 'get'
}).then(function (res) {
alert('登录成功')
})
}
}
}
</script>
点击登录按钮,我们看一下服务器的返回
登录成功后,服务器的响应消息头里有一个Set-Cookie,这里就是cookie的信息。
Vue不需要对这个cookie做任何处理,下次向服务器发送请求时,axios会自动把这个cookie携带在请求的消息头里面。下面我们向服务器发送一个请求,看一下客户端的请求头:
可以看到在请求标头里面有cookie的信息,然后请求也成功了。
因为客户端和服务器是完全分离的(域名和端口不同),所以会存在跨域的问题。这个问题在我的另一篇博客里有提到,博客地址:asp.net core+vue+signalr示例_begeneral的博客-CSDN博客
这里主要说明一个配置:AllowCredentials()。配置跨域时要调用这个函数,允许客户端携带cookie凭证。
在客户端处理cookie的时候,有一个地方卡了我很久(因为我刚开始学习前端):我之前一直以为客户端在登录成功后要手动保存cookie,然后在发送请求时也要手动在请求头中添加cookie。
后来查了一些资料,才知道只需设置axios在发送请求的时候携带凭证就可以了,所以这行代码很重要:axios.defaults.withCredentials = true