码云地址
https://gitee.com/Wolfmoor/uniapp_.netcore_LogonDemo
解决了什么问题:
登录验证、自动登录、加密解密token、前端缓存读写、后端session读写、后端中间件的使用
技术栈
- 前端:uniapp H5
- 后端:.netCore3.1 api
Demo思路

AES机制
AES可以将一个字符串进行加密生成另一个字符串,称之为token,所以每个token都可以代表一个用户
接口验证机制
每个接口都要验证token能否被解密,由于token是登录后才会产生的,所以token解密成功则代表已登录,即接口可以被调用
如何保证token不被伪造?
AES加密可以用密码,不知道密码就无法加密出相同的token
AES方法封装
#region AES加密解密
/// <summary>
/// 128位处理key
/// </summary>
/// <param name="keyArray">原字节</param>
/// <param name="key">处理key</param>
/// <returns></returns>
private static byte[] GetAesKey(byte[] keyArray, string key)
{
byte[] newArray = new byte[16];
if (keyArray.Length < 16)
{
for (int i = 0; i < newArray.Length; i++)
{
if (i >= keyArray.Length)
{
newArray[i] = 0;
}
else
{
newArray[i] = keyArray[i];
}
}
}
return newArray;
}
/// <summary>
/// 使用AES加密字符串,按128位处理key
/// </summary>
/// <param name="content">加密内容</param>
/// <param name="key">秘钥,需要128位、256位.....</param>
/// <returns>Base64字符串结果</returns>
public static string AesEncrypt(string content, string key, bool autoHandle = true)
{
byte[] keyArray = Encoding.UTF8.GetBytes(key);
if (autoHandle)
{
keyArray = GetAesKey(keyArray, key);
}
byte[] toEncryptArray = Encoding.UTF8.GetBytes(content);
SymmetricAlgorithm des = Aes.Create();
des.Key = keyArray;
des.Mode = CipherMode.ECB;
des.Padding = PaddingMode.PKCS7;
ICryptoTransform cTransform = des.CreateEncryptor();
byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
return Convert.ToBase64String(resultArray);
}
/// <summary>
/// 使用AES解密字符串,按128位处理key
/// </summary>
/// <param name="content">内容</param>
/// <param name="key">秘钥,需要128位、256位.....</param>
/// <returns>UTF8解密结果</returns>
public static string AesDecrypt(string content, string key, bool autoHandle = true)
{
byte[] keyArray = Encoding.UTF8.GetBytes(key);
if (autoHandle)
{
keyArray = GetAesKey(keyArray, key);
}
byte[] toEncryptArray = Convert.FromBase64String(content);
SymmetricAlgorithm des = Aes.Create();
des.Key = keyArray;
des.Mode = CipherMode.ECB;
des.Padding = PaddingMode.PKCS7;
ICryptoTransform cTransform = des.CreateDecryptor();
byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
return Encoding.UTF8.GetString(resultArray);
}
#endregion
前端设置状态/缓存
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
/**
* 是否需要强制登录
*/
forcedLogin: true,
hasLogin: false,
userName: "",
token: ""
},
mutations: {
login(state, res) {
state.userName = res.body.userId;
state.hasLogin = true;
state.token = res.token;
uni.setStorageSync('userInfo',res); //设置缓存
},
logout(state) {
state.userName = "";
state.hasLogin = false;
}
}
})
export default store
中间件类
其中的HttpContext 对象包含了请求/响应的数据,操作它就可以获取/修改请求上下文
using Microsoft.AspNetCore.Http;
using System;
using System.Globalization;
using System.IO;
using System.Threading.Tasks;
namespace AEStest
{
public class RequestMiddleware
{
private readonly RequestDelegate _next;
public RequestMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
try
{
//请求前操作
await _next(context);
//返回前操作
}
catch (Exception ex)
{
throw ex;
}
}
}
}
暴露中间件
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
namespace AEStest
{
public static class RequestMiddlewareExtensions
{
public static IApplicationBuilder UseRequestMiddleware(
this IApplicationBuilder builder)
{
return builder.UseMiddleware<RequestMiddleware>();
}
}
}
在Startup类注册中间件
在Configure方法里注册:
app.UseRequestMiddleware();
.netcore使用session
在Startup.cs文件中的ConfigureServices方法中添加:
services.AddSession();
在Startup.cs文件中的Configure方法中加上这一句代码
app.UseSession();
引用包
Microsoft.AspNetCore.Http
在中间件中使用:
public async Task Invoke(HttpContext context)
{
//请求前操作
context.Session.SetString("userID", userID);
await _next(context);
//返回前操作
}
在控制器中使用:
var userID = HttpContext.Session.GetString("userID");
前端读取缓存
this.userInfo = uni.getStorageSync('userInfo');
版权声明:本文为qq_20662097原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。