修正错误

This commit is contained in:
niyyzf 2024-07-02 16:08:07 +08:00
parent 29e1de60b4
commit 09136a7806
10 changed files with 49 additions and 86 deletions

View File

@ -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"]
}); });
} }

View File

@ -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);

View File

@ -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("你不具有访问此资源的权力"));
} }
} }

View File

@ -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>

View File

@ -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"
} }

View File

@ -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.

View File

@ -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}
}); });
// 如果验证成功,继续导航
// 直接从响应中获取状态码 return true;
const data = response as HttpType<any>; } catch (err) {
if (data.code !== 200) { toast.error('权限不足', {timeout: 3000});
toast.error('未登录', {timeout: 3000}) return navigateTo("/error/403");
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;
}); });

View File

@ -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);

View File

@ -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
} }