Angular-根据用户的登录ID重定向

时间:2019-06-19 13:12:22

标签: angular laravel api

我正在使用带有Laravel后端和Angular前端的应用程序。每个表都有与users表中的id相关的user_id,即User Model类。除了将用户ID为1的admin之外,其他所有内容都将显示。我希望任何登录的用户都应该根据登录ID进行重定向。

角度:auth.service.ts

import { Injectable } from '@angular/core';
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { HttpHeaders } from '@angular/common/http';
import { Router } from '@angular/router';
import { Observable, throwError } from 'rxjs';
import { catchError, map, tap } from 'rxjs/operators';

// App imports
import { environment } from '../../environments/environment.prod';
import { User } from '../models/user';
// Setup headers
const httpOptions = {
  headers: new HttpHeaders({
'Content-Type': 'application/json'
})
};

@Injectable({
providedIn: 'root'
})
export class AuthService {
 public currentUser: User;
 private readonly apiUrl = environment.apiUrl;
 private registerUrl = this.apiUrl + '/register';
 private loginUrl = this.apiUrl + '/login';

 constructor(
 private http: HttpClient,
 private router: Router) {}

 onRegister(user: User): Observable<User> {

const request = JSON.stringify(
  { name: user.name, username: user.username, email: user.email, password: user.password }
);

return this.http.post(this.registerUrl, request, httpOptions)
  .pipe(
    map((response: User) => {
      // Receive jwt token in the response
      const token: string = response['access_token'];
      // If we have a token, proceed
      if (token) {
        this.setToken(token);
        this.getUser().subscribe();
      }
      return response;
    }),
    catchError(error => this.handleError(error))
  );
  }

  onLogin(user: User): Observable<User> {

const request = JSON.stringify(
  { email: user.email, password: user.password }
);

return this.http.post(this.loginUrl, request, httpOptions)
  .pipe(
    map((response: User) => {
      // Receive jwt token in the response
      const token: string = response['access_token'];
      // If we have a token, proceed
      if (token) {
        this.setToken(token);
        this.getUser().subscribe();
      }
      return response;
    }),
    catchError(error => this.handleError(error))
  );
  }

  onLogout(): Observable<User> {
return this.http.post(this.apiUrl + '/logout', httpOptions).pipe(
  tap(
    () => {
      localStorage.removeItem('token');
      this.router.navigate(['/']);
    }
   )
 );
 }

setToken(token: string): void {
return localStorage.setItem('token', token );
}

getToken(): string {
return localStorage.getItem('token');
}

getUser(): Observable<User> {
return this.http.get(this.apiUrl + '/me').pipe(
  tap(
    (user: User) => {
      this.currentUser = user;
    }
  )
 );
}

isAuthenticated(): boolean {
// get the token
const token: string = this.getToken();
if (token) {
  return true;
}
return false;
}

private handleError(error: HttpErrorResponse) {
if (error.error instanceof ErrorEvent) {
  // A client-side error.
  console.error('An error occurred:', error.error.message);
} else {
  // The backend error.
    return throwError(error);
}
// return a custom error message
return throwError('Ohps something wrong happen here; please try again 
later.');
  }
}

login.component.ts

 public function indexShortcode(Request $request)
{
if(Auth::user()->id == 1)
    $shortcodes = Shortcode::all();
import { Component, OnInit } from '@angular/core';
import { FormGroup,  FormBuilder,  Validators } from '@angular/forms';
import { FlashMessagesService } from 'angular2-flash-messages';
import { ActivatedRoute, Router } from '@angular/router';
import {UserService} from '../../services/user.service';
import { SnotifyService } from 'ng-snotify';

// App imports
import { AuthService } from '../../services/auth.service';
import { User } from '../../models/user';

@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.scss']
})
export class LoginComponent implements OnInit {
user: User = new User();
error: any;
returnUrl: string;

constructor(
private authService: AuthService,
private router: Router,
private route: ActivatedRoute,
private notify: SnotifyService
) { }  


 ngOnInit() {
 //  Set the return url
 this.returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/home';
}

onSubmit(loginForm): void {
this.authService.onLogin(this.user).subscribe(
  (response) => {
    // get return url from route parameters or default to '/'
    this.notify.success('Done, you have successfully logged in.', {timeout:2000, position: "rightTop"})        
    this.router.navigate([this.returnUrl]);
  },
  (error) => {
    this.error = error.error;
  }
);
// Clear form fields
loginForm.reset();
}  
}
}

login.component.ts

 public function login(Request $request)
{
$validator = Validator::make($request->all(), [
    'email' => 'required|string|email|max:255',
    'password'=> 'required'
]);

if ($validator->fails()) {
    return response()->json($validator->errors(), 422);
}

$credentials = $request->only(['email', 'password']);

if (!$token = auth()->attempt($credentials)) {
    return response()->json(['error' => 'Invalid Credentials'], 400);
}

$current_user = $request->email;

return response()->json([
'access_token' => $token,
'token_type' => 'bearer',
'current_user' => $current_user,
'expires_in' => auth()->factory()->getTTL() * 60
], 200);
}  

auth.guard.ts

import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } 
from '@angular/router';
import { Observable } from 'rxjs';
import { AuthService } from '../services/auth.service';

@Injectable()
export class AuthGuard implements CanActivate {

 constructor(
private router: Router,
private auth: AuthService) {}

canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | 
 boolean {

  if (this.auth.isAuthenticated()) {
    // logged in so return true
    return true;
  }

  // not logged in so redirect to login page with the return url
  this.router.navigate(['/login'], { queryParams: { returnUrl: state.url 
}});

  return true;
 }
}

auth.guard.spec.ts

import { RouterTestingModule } from '@angular/router/testing';
import { TestBed, async, inject } from '@angular/core/testing';
import { HttpClient, HttpHandler } from '@angular/common/http';
import { Router } from '@angular/router';

//  App imports
import { AuthGuard } from './auth.guard';
import { AuthService } from '../services/auth.service';

describe('AuthGuard Tests: ', () => {
const router = {
  navigate: jasmine.createSpy('navigate')
 };

beforeEach(async(() => {
TestBed.configureTestingModule({
  imports: [
    RouterTestingModule.withRoutes([
      {path: 'shortcode:id'}
    ])
  ],
  providers: [AuthGuard, AuthService, HttpClient, HttpHandler, { provide: 
Router, useValue: router } ]
});
 }));

   it('should AuthGuartd to be defined', inject([AuthGuard], (guard: AuthGuard) 
=> {
expect(guard).toBeTruthy();
}));

it('should AuthService to be defined', inject([AuthService], (auth: 
AuthService) => {
expect(auth).toBeTruthy();
}));

});

如果login user()-> id为1,则应重定向到admindashboard,如果不是1,则应重定向到userdashboard。

1 个答案:

答案 0 :(得分:0)

通过laravel中的登录功能,您将返回一个字段current_user,其中仅包含当前用户的电子邮件。对于更健壮的应用程序,建议将该用户的每个重要细节都返回到前端,这是更灵活的做法。如果用户表中的电子邮件字段是唯一的,则应发送查询来搜索用户并将该值分配给变量,例如:

$user = User::where('email',$request['email'])->get()->first();

并将$user分配给current_user

return response()->json([
    'access_token' => $token,
    'token_type' => 'bearer',
    'current_user' => $user,
    'expires_in' => auth()->factory()->getTTL() * 60
], 200);

然后在onSubmit(loginForm)函数中,在重定向之前,您可以从响应中指定一个条件:

if(response.current_user.role_id==1){
    this.route.navigate(['admindashboard'],response.current_user.id);
} else {
    this.route.navigate(['userdashboard'],response.current_user.id);
}

我希望这是问题的答案,或者为您提供解决方法的逻辑。