node.js - 在我的 MEAN 堆栈应用程序中成功登录后如何实现角色重定向
问题描述
我已经开发了一个 MEAN 堆栈应用程序,后端工作正常,前端但我想通过在登录后实现基于角色的重定向来更进一步,我有 5 个角色,即管理员、教师、护士、运动员和看门人,我希望他们每个人都能登录成功后访问他/她自己的页面,并且应该使用相同的登录页面
我已经在网上尝试了一些解决方案,但到目前为止没有任何帮助我这是第五次在没有真正解决方案的情况下提出这个问题,请帮我解决这个问题,这是我最后一年的项目
这是我的路线.ts
```import { Routes } from '@angular/router';
import { UserComponent } from './user/user.component';
import { SignUpComponent } from './user/sign-up/sign-up.component';
import { SignInComponent } from './user/sign-in/sign-in.component';
import { AuthGuard } from './auth/auth.guard';
import { AdminComponent } from './user/admin/admin.component';
import { AdminSportComponent} from './user/admin-sport/admin-sport.component'
import { AdminSuaHubComponent } from './user/admin-sua-hub/admin-sua-hub.component';
import { AdminCictComponent } from './user/admin-cict/admin-cict.component';
import { ViewadminsectionsComponent } from './user/viewadminsections/viewadminsections.component'
import { from } from 'rxjs';
export const appRoutes: Routes = [
{
path: 'user',component:SignInComponent
},
{
path:'signup', component:SignUpComponent, canActivate:[AuthGuard]
},
{
path:'admin', component:AdminComponent,
canActivate:[AuthGuard],
data:{
roles:['admin']
}
},
{
path:'viewsectionadmins',
component:ViewadminsectionsComponent,
canActivate:[AuthGuard],
data:{
roles:['admin']
}
},
{
path:'admincict',
component:AdminCictComponent,
canActivate:[AuthGuard],
data:{
roles:['admincict']
}
},
{
path:'adminsport',
component:AdminSportComponent,
canActivate:[AuthGuard],
data:{
roles:['adminsport']
}
},
{
path:'adminsuahub',
component: AdminSuaHubComponent,
canActivate:[AuthGuard],
data:{
roles:['adminsuahub']
}
},
{
path: '',component:SignInComponent
},
{
path:'',redirectTo:'/user', pathMatch:'full'
}
];```
这是我的 app.module.ts
```import { BrowserModule } from '@angular/platform-browser';
import { NgModule, forwardRef } from '@angular/core';
import{ FormsModule } from '@angular/forms';
import{ RouterModule } from '@angular/router'
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http'
//components
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { UserComponent } from './user/user.component';
import { SignUpComponent } from './user/sign-up/sign-up.component';
import { from } from 'rxjs';
//routes
import { appRoutes } from './routes';
import { SignInComponent } from './user/sign-in/sign-in.component';
import { UserService } from './shared/user.service';
import { AuthGuard } from './auth/auth.guard';
import { AuthInterceptor } from './auth/auth.interceptor';
import { AdminComponent } from './user/admin/admin.component';
import { AdminSportComponent } from './user/admin-sport/admin-sport.component';
import { AdminSuaHubComponent } from './user/admin-sua-hub/admin-sua-hub.component';
import { AdminCictComponent } from './user/admin-cict/admin-cict.component';
import { ViewadminsectionsComponent } from './user/viewadminsections/viewadminsections.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
@NgModule({
declarations: [
AppComponent,
UserComponent,
SignUpComponent,
SignInComponent,
AdminComponent,
AdminSportComponent,
AdminSuaHubComponent,
AdminCictComponent,
ViewadminsectionsComponent
],
imports: [
BrowserModule,
AppRoutingModule,
FormsModule,
RouterModule.forRoot(appRoutes),
HttpClientModule,
BrowserAnimationsModule
],
providers: [{
provide:forwardRef(() => {HTTP_INTERCEPTORS}),
useClass:forwardRef(() =>{ AuthInterceptor}),
multi:true
},AuthGuard,UserService],
bootstrap: [AppComponent]
})
export class AppModule { }```
这是我的 User.js
``` const mongoose = require('mongoose');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const userSchema = new mongoose.Schema({
fullname:{
type:String,
required:'Full name cant be empty',
min:6,
max:255
},
email:{
type:String,
required:'Email cant be Empty',
max:255,
unique:true
},
University:{
type:String,
default:"Sokoine University of Agriculture"
},
College:{
type:String,
required:'College cant be Empty'
},
Department:{
type:String,
required:'department cant be empty'
},
password:{
type:String,
required:'pasword cant be empty',
max :1024,
minlength: [6,'password must be atlest 6 character long']
},
admintype:{
type:String,
enum :['HOD','CICT','Sports','SUASAB','Admin']
},
date:{
type:Date,
default:Date.now
},
saltSecret:String
});
//custom validation
userSchema.path('email').validate((val) => {
emailRegex = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
return emailRegex.test(val);
},'Invalid E-mail. ');
//events
userSchema.pre('save', function(next) {
bcrypt.genSalt(10, (err, salt)=> {
bcrypt.hash(this.password, salt, (err, hash) => {
this.password = hash;
this.saltSecret = salt;
next();
});
});
});
//methods
userSchema.methods.verifyPassword = function(password){
return bcrypt.compareSync(password, this.password);
};
userSchema.methods.generateJwt = function() {
return jwt.sign({ _id:this._id},
process.env.JWT_SECRET,
{expiresIn:process.env.JWT_EXP});
}
module.exports = mongoose.model('User',userSchema)```
这是我的 user.controller.js
```const mongoose = require('mongoose');
const User = mongoose.model('User');
const passport = require('passport');
const _ = require('lodash');
module.exports.register = (req,res, next) => {
const user = new User();
user.fullname = req.body.fullname;
user.email = req.body.email;
user.College = req.body.College;
user.Department = req.body.Department;
user.password = req.body.password;
user.admintype = req.body.admintype;
user.save((err, doc) => {
if(!err) { res.send(doc)}
else
{
if(err.code == 11000)
res.status(422).send(['Duplicate email Address Found.'])
else
return next(err);
}
})
}
module.exports.authenticate = (req, res, next ) => {
//calll for passport authentication
passport.authenticate('local', (err, user, info) => {
//error form paasport middleware
if(err) return res.status(400).json(err);
//registered user
else if (user) return res.status(200).json({ "token":user.generateJwt() });
//unknown user or wrong password
else return res.status(404).json(info);
})(req, res);
}
module.exports.userProfile = (req, res, next) =>{
User.findOne({ _id:req._id},
(err,user) =>{
if(!user)
return res.status(404).json({ status: false, message : 'User Record not Found. '});
else
return res.status(200).json({ status:true , user : _.pick(user, ['fullname','email','university','College','Department','admintype'])});
} );
//get admins
}```
这是我的 auth.guard.ts
```import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree } from '@angular/router';
import { Observable } from 'rxjs';
import { UserService } from '../shared/user.service';
import { Router } from '@angular/router';
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
constructor(private userService:UserService,private router: Router) {}
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): boolean {
if(!this.userService.isloggedIn()){
this.router.navigateByUrl('/user');
this.userService.deleteToken();
return false;
}
return true;
}
}```
这是我的 user.model.ts
```export class User {
fullname:string;
email:string;
university:string;
College:string;
Department:string;
password:string;
admintype:string;
}```
这是我的 user.service.ts
```import { Injectable } from '@angular/core';
import { User } from './user.model';
import{ HttpClient, HttpHeaders } from '@angular/common/http';
import{ environment } from '../../environments/environment';
import { from } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class UserService {
selectedUser: User = {
fullname:'',
email:'',
university:'',
College:'',
Department:'',
password:'',
admintype:''
}
noAuthHeader = { headers: new HttpHeaders({ 'NoAuth': 'True'})};
constructor(private http: HttpClient) { }
//http methods
postUser(user:User)
{
return this.http.post(environment.apiBaseUrl+ '/register' ,user)
}
login(authCredentials)
{
return this.http.post(environment.apiBaseUrl+ '/authenticate',authCredentials,this.noAuthHeader);
}
getUserProfile()
{
return this.http.get(environment.apiBaseUrl + '/userProfile');
}
//helper methods
setToken(token:string)
{
localStorage.setItem('token',token);
}
getToken()
{
localStorage.getItem('token');
}
deleteToken()
{
localStorage.removeItem('token');
}
getUserPayload(){
var token = localStorage.getItem('token');
if(token)
{
var userPayload = atob(token.split('.')[1]);
return JSON.parse(userPayload);
}
else
return null;
}
isloggedIn()
{
var userPayload = this.getUserPayload();
if (userPayload)
{
return userPayload.exp > Date.now() / 1000;
}
}
getUserRole()
{
}
}```
这是我的登录.component.ts
```import { Component, OnInit } from '@angular/core';
import { NgForm } from '@angular/forms';
import { UserService } from 'src/app/shared/user.service';
import { Router } from '@angular/router';
@Component({
selector: 'app-sign-in',
templateUrl: './sign-in.component.html',
styleUrls: ['./sign-in.component.css']
})
export class SignInComponent implements OnInit {
constructor( private userService:UserService, private router:Router) { }
model = {
email:'',
password:''
};
emailRegex = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
serverErrorMessages : string;
ngOnInit() {
if(this.userService.isloggedIn())
{
this.router.navigateByUrl('/admin');
}
}
onSubmit(form :NgForm)
{
this.userService.login(form.value).subscribe(
res =>{
this.userService.setToken(res['token']);
this.router.navigateByUrl('/admin');
},
err =>{
this.serverErrorMessages = err.message;
});
}
}```
到目前为止,我没有错误,但需要实现基于角色的重定向
解决方案
我建议您以管理员身份在 mongodb 架构中创建一个字段,布尔值为 true 或 false,具体取决于用户,如果存在任何其他角色,请添加不同的字段,
登录时检查用户管理员状态,并通过订阅服务文件中的可观察对象通知应用程序的其他部分
在组件的 OnInit 方法上调用服务文件中的方法并检查用户是否为管理员,如果不是管理员,则隐藏您不想显示的内容
并阻止用户转到用于管理员的路由,添加一个守卫,如果他不是管理员,则通过检查您在服务文件中创建的相同可观察对象将用户导航到主页。
我希望它有帮助
推荐阅读
- r - 如何使用 which 函数来搜索我的数据框?
- python - 在不触发回调的情况下修改 matplotlib TextBox 值
- java - 将值从构造函数传递给方法
- solr - 在 SOLR 中搜索空值/未设置值
- python - 如何使用 winsound 阻止声音堆叠在一起?(Python 和 tkinter)
- c# - Quartz.net 3 触发器触发另一个工作
- python - 如何在 python 中常规检查 ValueError?
- c++ - 如何检查两个数组是否相同或不同
- git - 如何向我的 Git GUI SmartGit 添加自定义路径?
- windows - 如果语句未按预期执行 - 批处理文件