修正错误
This commit is contained in:
parent
29e1de60b4
commit
09136a7806
|
@ -116,7 +116,7 @@ public class ApplicationDbContext(DbContextOptions<ApplicationDbContext> options
|
||||||
NormalizedName = roleName.ToUpperInvariant(),
|
NormalizedName = roleName.ToUpperInvariant(),
|
||||||
ApiPermissions =
|
ApiPermissions =
|
||||||
["1","2","3","4","5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20","21","22","23","24","25","26","27","28","29","30","31","32","33","34","35"],
|
["1","2","3","4","5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20","21","22","23","24","25","26","27","28","29","30","31","32","33","34","35"],
|
||||||
RouterPermissions = ["1", "2", "3", "4","5","6","7","8","9","10","11","12","13","14","15","16"]
|
RouterPermissions = ["1", "3", "4","5","6","7","8","9","10","11","12","13","14","15","16"]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -81,6 +81,17 @@ public class AccountController(
|
||||||
user.Id
|
user.Id
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
//创建修改密码令牌
|
||||||
|
var tokenPassword = await userManager.GeneratePasswordResetTokenAsync(user);
|
||||||
|
if (user.PasswordExpiredDate == null || user.PasswordExpiredDate < DateTimeOffset.Now)
|
||||||
|
{
|
||||||
|
//返回402
|
||||||
|
return StatusCode(402,new
|
||||||
|
{
|
||||||
|
tokenPassword,
|
||||||
|
user.Id,
|
||||||
|
});
|
||||||
|
}
|
||||||
var roles = await userManager.GetRolesAsync(user);
|
var roles = await userManager.GetRolesAsync(user);
|
||||||
var roleId = roles.ToList()[0]; // 直接获取角色ID列表
|
var roleId = roles.ToList()[0]; // 直接获取角色ID列表
|
||||||
var claimsIdentity = new ClaimsIdentity(new[]
|
var claimsIdentity = new ClaimsIdentity(new[]
|
||||||
|
@ -90,15 +101,6 @@ public class AccountController(
|
||||||
new Claim(ClaimTypes.Role, roleId.ToLower()) // 将角色ID列表转换为逗号分隔的字符串
|
new Claim(ClaimTypes.Role, roleId.ToLower()) // 将角色ID列表转换为逗号分隔的字符串
|
||||||
});
|
});
|
||||||
var token = tokenHelper.GenerateToken(claimsIdentity);
|
var token = tokenHelper.GenerateToken(claimsIdentity);
|
||||||
if (user.PasswordExpiredDate == null || user.PasswordExpiredDate < DateTimeOffset.Now)
|
|
||||||
{
|
|
||||||
//返回402
|
|
||||||
return StatusCode(402,new
|
|
||||||
{
|
|
||||||
token,
|
|
||||||
user.Id,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return Ok(new
|
return Ok(new
|
||||||
{
|
{
|
||||||
|
@ -128,32 +130,14 @@ public class AccountController(
|
||||||
return Ok("邮件已发送");
|
return Ok("邮件已发送");
|
||||||
}
|
}
|
||||||
[HttpGet("ChangePassword")]
|
[HttpGet("ChangePassword")]
|
||||||
public async Task<IActionResult> ChangePassword([FromQuery] string currentPassword,[FromQuery] string newPassword)
|
public async Task<IActionResult> ChangePassword([FromQuery] string userId, [FromQuery] string token,[FromQuery] string newPassword)
|
||||||
{
|
{
|
||||||
// 获取当前经过身份验证的用户
|
// 获取当前经过身份验证的用户
|
||||||
var authenticatedUser = await userManager.GetUserAsync(HttpContext.User);
|
var authenticatedUser = await userManager.FindByIdAsync(userId);
|
||||||
|
|
||||||
if (authenticatedUser == null)
|
if (authenticatedUser == null)
|
||||||
{
|
{
|
||||||
return BadRequest("用户未登录");
|
return BadRequest("用户不存在");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查当前密码是否正确
|
|
||||||
var isCurrentPasswordValid = await userManager.CheckPasswordAsync(authenticatedUser, currentPassword);
|
|
||||||
if (!isCurrentPasswordValid)
|
|
||||||
{
|
|
||||||
return BadRequest("当前密码不正确");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检查新密码是否与旧密码相同
|
|
||||||
if (currentPassword == newPassword)
|
|
||||||
{
|
|
||||||
return BadRequest("新密码不能与旧密码相同");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 生成密码重置令牌
|
|
||||||
var token = await userManager.GeneratePasswordResetTokenAsync(authenticatedUser);
|
|
||||||
|
|
||||||
// 重置密码
|
// 重置密码
|
||||||
var result = await userManager.ResetPasswordAsync(authenticatedUser, token, newPassword);
|
var result = await userManager.ResetPasswordAsync(authenticatedUser, token, newPassword);
|
||||||
|
|
||||||
|
|
|
@ -21,10 +21,15 @@ public class RoteController(
|
||||||
var rotes = role!.RouterPermissions.ToList();
|
var rotes = role!.RouterPermissions.ToList();
|
||||||
//获取路由列表
|
//获取路由列表
|
||||||
var apiPermissions = dbContext.RotePermissions.ToList().Where(x => rotes.Any(y => y == x.Id.ToString())).Select(x=>x.Router).ToList();
|
var apiPermissions = dbContext.RotePermissions.ToList().Where(x => rotes.Any(y => y == x.Id.ToString())).Select(x=>x.Router).ToList();
|
||||||
|
//如果rotes 中包括*
|
||||||
|
if (rotes.Contains("*"))
|
||||||
|
{
|
||||||
|
return Ok("权限验证通过");
|
||||||
|
}
|
||||||
//将path全部小写
|
//将path全部小写
|
||||||
path = path.ToLower();
|
path = path.ToLower();
|
||||||
//使用正则匹配
|
//使用正则匹配
|
||||||
var firstOrDefault = apiPermissions.FirstOrDefault(x => Regex.IsMatch(path,x));
|
var firstOrDefault = apiPermissions.FirstOrDefault(x => Regex.IsMatch(path,x));
|
||||||
return Ok(firstOrDefault != null ? new ApiResponse(ApiResponseState.Success) : new ApiResponse(ApiResponseState.Forbidden));
|
return Ok(firstOrDefault != null ? Ok("权限验证通过") : Unauthorized("你不具有访问此资源的权力"));
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -43,9 +43,6 @@
|
||||||
<None Update="app.db">
|
<None Update="app.db">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
<None Update="apptemp.db">
|
|
||||||
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
|
||||||
</None>
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
"dotnetRunMessages": true,
|
"dotnetRunMessages": true,
|
||||||
"launchBrowser": false,
|
"launchBrowser": false,
|
||||||
"launchUrl": "swagger",
|
"launchUrl": "swagger",
|
||||||
"applicationUrl": "http://192.168.0.13:5253",
|
"applicationUrl": "http://127.0.0.1:5000",
|
||||||
"environmentVariables": {
|
"environmentVariables": {
|
||||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,5 +20,5 @@
|
||||||
"Secret": "p4Qzf/+GPP/XNLalZGCzwlelOl6skiFZscj6iZ6rZZE=",
|
"Secret": "p4Qzf/+GPP/XNLalZGCzwlelOl6skiFZscj6iZ6rZZE=",
|
||||||
"Issuer": "LoongPanel",
|
"Issuer": "LoongPanel",
|
||||||
"Audience": "LoongPanel",
|
"Audience": "LoongPanel",
|
||||||
"PubLicApi": "/Api/Account/Login;/Api/Account/VerifyEmail;/Api/Account/ForgotPassword;/Api/Account/ResetPassword;"
|
"PubLicApi": "/Api/Account/Login;/Api/Account/VerifyEmail;/Api/Account/ForgotPassword;/Api/Account/ResetPassword;/Api/Account/ChangePassword"
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
|
@ -1,9 +1,7 @@
|
||||||
import type {HttpType} from "~/types/baseType";
|
|
||||||
import {defineNuxtRouteMiddleware} from "#app";
|
import {defineNuxtRouteMiddleware} from "#app";
|
||||||
import {useToast} from 'vue-toastification'
|
import {useToast} from 'vue-toastification'
|
||||||
|
|
||||||
interface RouteBackType extends HttpType<any> {
|
|
||||||
}
|
|
||||||
|
|
||||||
export default defineNuxtRouteMiddleware(async (to, from) => {
|
export default defineNuxtRouteMiddleware(async (to, from) => {
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
|
@ -21,9 +19,8 @@ export default defineNuxtRouteMiddleware(async (to, from) => {
|
||||||
|
|
||||||
// 获取当前导航路径
|
// 获取当前导航路径
|
||||||
const currentPath = to.path;
|
const currentPath = to.path;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await $fetch('/Api/Rote/RoteVerify', {
|
await $fetch('/Api/Rote/RoteVerify', {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
headers: {
|
headers: {
|
||||||
'Authorization': 'Bearer ' + token
|
'Authorization': 'Bearer ' + token
|
||||||
|
@ -31,27 +28,10 @@ export default defineNuxtRouteMiddleware(async (to, from) => {
|
||||||
baseURL: runtimeConfig.public.baseUrl,
|
baseURL: runtimeConfig.public.baseUrl,
|
||||||
params: {'path': currentPath}
|
params: {'path': currentPath}
|
||||||
});
|
});
|
||||||
|
// 如果验证成功,继续导航
|
||||||
// 直接从响应中获取状态码
|
|
||||||
const data = response as HttpType<any>;
|
|
||||||
if (data.code !== 200) {
|
|
||||||
toast.error('未登录', {timeout: 3000})
|
|
||||||
|
|
||||||
if (data.code === 403) {
|
|
||||||
if (to.path === from.path) {
|
|
||||||
return navigateTo("/Home");
|
|
||||||
}
|
|
||||||
return navigateTo(from.path);
|
|
||||||
}
|
|
||||||
|
|
||||||
return navigateTo("/SignIn");
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
// 处理错误情况
|
|
||||||
console.error('请求验证路由时发生错误:', error);
|
|
||||||
toast.error('请求错误', {timeout: 3000})
|
|
||||||
return navigateTo("/SignIn");
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
} catch (err) {
|
||||||
|
toast.error('权限不足', {timeout: 3000});
|
||||||
|
return navigateTo("/error/403");
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
definePageMeta({
|
definePageMeta({
|
||||||
layout: 'login',
|
layout: 'login',
|
||||||
middleware: ['auth']
|
|
||||||
})
|
})
|
||||||
//导入yup
|
//导入yup
|
||||||
import * as yup from 'yup'
|
import * as yup from 'yup'
|
||||||
|
@ -9,16 +8,13 @@ import {useToast} from "vue-toastification";
|
||||||
import Vcode from 'vue3-puzzle-vcode';
|
import Vcode from 'vue3-puzzle-vcode';
|
||||||
//创建表单
|
//创建表单
|
||||||
const form = reactive({
|
const form = reactive({
|
||||||
currentPassword:'',
|
|
||||||
password: '',
|
password: '',
|
||||||
confirmPassword: ''
|
confirmPassword: ''
|
||||||
})
|
})
|
||||||
|
const userId = useRoute().query.id;
|
||||||
const isShow=ref(false);
|
const isShow=ref(false);
|
||||||
const toast=useToast()
|
const toast=useToast()
|
||||||
const schema = yup.object().shape({
|
const schema = yup.object().shape({
|
||||||
currentPassword:yup.string()
|
|
||||||
.required('密码为必填项')
|
|
||||||
.min(8, '密码至少需要8个字符'),
|
|
||||||
password: yup.string()
|
password: yup.string()
|
||||||
.required('密码为必填项')
|
.required('密码为必填项')
|
||||||
.min(8, '密码至少需要8个字符')
|
.min(8, '密码至少需要8个字符')
|
||||||
|
@ -53,16 +49,14 @@ const onSuccess=()=>{
|
||||||
$fetch('/Api/Account/ChangePassword', {
|
$fetch('/Api/Account/ChangePassword', {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
params:{
|
params:{
|
||||||
CurrentPassword:form.currentPassword,
|
userId:userId,
|
||||||
NewPassword:form.password,
|
NewPassword:form.password,
|
||||||
},
|
token:useCookie('tokenPassword').value??""
|
||||||
headers: {
|
|
||||||
'Authorization': 'Bearer ' + useCookie('token').value
|
|
||||||
},
|
},
|
||||||
baseURL: useRuntimeConfig().public.baseUrl,
|
baseURL: useRuntimeConfig().public.baseUrl,
|
||||||
}).then((res) => {
|
}).then((res) => {
|
||||||
//清除临时token
|
//清除临时token
|
||||||
useCookie('token').value = ""
|
useCookie('tokenPassword').value = ""
|
||||||
toast.success(res)
|
toast.success(res)
|
||||||
setTimeout(()=>{
|
setTimeout(()=>{
|
||||||
navigateTo("/SignIn")
|
navigateTo("/SignIn")
|
||||||
|
@ -79,15 +73,11 @@ const onSuccess=()=>{
|
||||||
<div class="change-password-layout">
|
<div class="change-password-layout">
|
||||||
<Vcode :show="isShow" @success="onSuccess"/>
|
<Vcode :show="isShow" @success="onSuccess"/>
|
||||||
<NuxtLink href="/signIn">< 返回</NuxtLink>
|
<NuxtLink href="/signIn">< 返回</NuxtLink>
|
||||||
<div class="info">
|
<div class="info" v-if="userId">
|
||||||
<h1>修改你的密码 👍</h1>
|
<h1>修改你的密码 👍</h1>
|
||||||
<h2>当前账号密码已过期,请重新设置以继续登录</h2>
|
<h2>当前账号密码已过期,请重新设置以继续登录</h2>
|
||||||
</div>
|
</div >
|
||||||
<form class="form-box" @submit.prevent="handleSubmit">
|
<form class="form-box" @submit.prevent="handleSubmit" v-if="userId">
|
||||||
<div class="form-item">
|
|
||||||
<label>当前密码</label>
|
|
||||||
<input placeholder="最少8位" required type="password" minlength="8" v-model="form.currentPassword">
|
|
||||||
</div>
|
|
||||||
<div class="form-item">
|
<div class="form-item">
|
||||||
<label>新的密码</label>
|
<label>新的密码</label>
|
||||||
<input placeholder="最少8位" required type="password" minlength="8" v-model="form.password">
|
<input placeholder="最少8位" required type="password" minlength="8" v-model="form.password">
|
||||||
|
@ -98,11 +88,12 @@ const onSuccess=()=>{
|
||||||
</div>
|
</div>
|
||||||
<button type="submit">提交</button>
|
<button type="submit">提交</button>
|
||||||
</form>
|
</form>
|
||||||
|
<h1 v-else>!错误的请求</h1>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "base";
|
@import "../base";
|
||||||
.change-password-layout{
|
.change-password-layout{
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-rows: repeat(3,auto);
|
grid-template-rows: repeat(3,auto);
|
|
@ -60,11 +60,17 @@ const onSuccess = () => {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if(err.response.status===402){
|
if(err.response.status===402){
|
||||||
toast.error('登录失败,密码过期,请修改密码')
|
toast.info('登录失败,密码过期,请修改密码')
|
||||||
const data=err.response._data
|
const data=err.response._data
|
||||||
useCookie('token').value =data.token;
|
useCookie('tokenPassword').value =data.tokenPassword;
|
||||||
setTimeout(()=>{
|
setTimeout(()=>{
|
||||||
navigateTo(`/changePassword/${data.id}`)
|
navigateTo({
|
||||||
|
path:'/changePassword',
|
||||||
|
query:{
|
||||||
|
id:data.id
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
},2000)
|
},2000)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue