1. 程式人生 > 其它 >Angular實戰專案記錄(一)------登入(傳遞引數,獲取返回值,加密密碼,路由守衛,localStorage)

Angular實戰專案記錄(一)------登入(傳遞引數,獲取返回值,加密密碼,路由守衛,localStorage)

技術標籤:angular專案實戰

需求:angular登入(傳遞引數,獲取返回值,加密密碼,local路由守衛,localStorage)

需要的模組

  • home.routing.ts
  • login.component.html
  • login.component.ts
  • login.service.ts
  • login.guard.ts
  • storage.service.ts

步驟:

一,雙向繫結input框的賬號和密碼

login.html

          <input type="text"  name="username"  placeholder="使用者名稱" autocomplete="off" [(ngModel)]="username" >
          <input type="password"  name="password"  placeholder="密碼" [(ngModel)]="password">
     	   <span class="redalert" >  {{loginErrorInfo}}</span>
            <button type="submit" (click)="login()" >{{denglu}}</button>
       

login.ts

 public denglu:string = '登入'
  public username:any ='';
  private password:any ='';

二,將賬號和密碼(加密)進行處理,向api介面傳送請求,傳遞引數

2.1請求資料
2.1.1在app.module.ts中引入HttpClientModule類注入
app.module.ts (其他的元件沒有寫,僅寫了新增)

//引入元件
import { HttpClientModule } from '@angular/common/http';//通過HTTP協議實現前端應用和後端伺服器的通訊

  imports: [  //引入當前模組執行依賴的其他模組
    HttpClientModule,
  ]

2.1.2在用到的地方引入HttpClient並在建構函式中宣告
建立一個服務: ng g s login
login.service.ts

import { HttpClient, HttpHeaders} from '@angular/common/http';
constructor(private http: HttpClient) { }

2.1.3get請求引數(我這裡是get請求)
我這裡寫的請求資料可能有點複雜,目前的技能只是這樣
login.service.ts

 // 登入
  login(params) {

    return new Promise((resolve,reject)=>{
      this.http.get('api/login/',{'params':params, 'headers': {
        'Content-Type': 'application/json; charset=UTF-8',
    }, withCredentials: true}).subscribe((res)=>{
      resolve(res)
     
    },error=>{
      reject(error)
     // console.log('username or password error')
    })

    })
   
  }

2.2請求資料,並處理引數(加密密碼)
我這裡使用到了localStorage暫時儲存,為了接下來的路由守衛功能
login.ts

//請求資料的服務
import {LoginService} from './login.service';
//本地儲存的服務
import { StorageService } from 'src/app/auth/storage.service';
//跳轉路由的模組
import {Router} from '@angular/router';

  public username:any ='';
  private password:any ='';
  public user:any; //賬號密碼
   private loginErrorInfo = ''; //提示報錯

 // 登入
  login() {
    this.user ={}
    this.user={
      username:this.username,
      password:this.password
    }
    
 constructor(private loginService: LoginService, private RootRouter: Router,private storage:StorageService) { }
 

    //將密碼進行加密
    this.user.password = btoa(this.password)
    console.log(this.user)
    if (this.user.username === '' || this.user.password === '') {
      this.loginErrorInfo = '使用者名稱或密碼不能為空';
    } else {
      // TODO
      this.loginErrorInfo = '';
    }
    this.loginService.login(this.user)
    .then(
      (data:any) => {
        console.log(data)
        this.denglu = '登入中...'
        if(data['code']=== 2000){
          this.storage.set('username',data['username'])
          this.storage.set('user_id',data['user_id'])
           //localStorage.setItem("currentUser",this.username);
          this.RootRouter.navigateByUrl('home');// 路由跳轉
        }
      
      }, 
      err => {
        this.denglu = '登入'
        console.log(err)
        this.loginErrorInfo = err.error.text
       
      }
    )
  }

請求成功的返回值
在這裡插入圖片描述
請求失敗的返回值,將它返回,展示在頁面上
在這裡插入圖片描述

三,localStorage的使用封裝

建立這個服務: ng g s storage

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class StorageService {

  constructor() { }
  //儲存資料,屬性,值
  set(key:string,value:any){
    localStorage.setItem(key,JSON.stringify(value))
  }
  //通過屬性讀取值
  get(key:string){
    return JSON.parse(localStorage.getItem(key))
  }
  //通過屬性移除值
  remove(key:string){
    localStorage.removeItem(key);
  }
}

四,路由守衛

當用戶滿足一定條件才會被允許進入或離開路由,當用戶登入並擁有一些許可權才能進入某些路由
eg:登入,儲存

**CanActivate:**處理導航到某路由的情況
CanDeactivate:處理從當前路由離開的情況
**Resolve:**在路由啟用之前獲取路由資料

CanActivate判斷使用者許可權
1.建立一個login.guard.ts
ng g guard login
2.LoginGuard類實現CanActivate介面,返回true或false,Angular根據返回值判斷路由通過或不通過
guard用來保護一個路經,當用戶滿足一定條件下才可開啟相對應介面

login.guard.ts
在這裡需要用localStorage剛剛儲存的資料

import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot, UrlTree } from '@angular/router';
import { Observable } from 'rxjs';
import { StorageService } from './storage.service';

@Injectable({
  providedIn: 'root'
})
export class LoginGuard implements CanActivate {
  constructor(
    private router: Router,
    private storage:StorageService
  ) { }
  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean | UrlTree | Observable<boolean | UrlTree> | Promise<boolean | UrlTree> {
    //throw new Error('Method not implemented.');
   let userinfo = this.storage.get('username')
   let user_id = this.storage.get('user_id')
   console.log(userinfo)
    console.log('我運行了')
   if(!userinfo || !user_id){
     //return false
      alert('請登入')
     this.router.navigate(['/login'])
   }else{
     return true
   }
  }

 

五,路由守衛的應用

在你所需要攔截的模組裡面的 routing.ts中應用
比如: home.routing.ts
引入守衛並配置

import { NgModule } from '@angular/core';

import { Routes, RouterModule } from '@angular/router';
//路由裡面的元件
import { HomeComponent } from './home.component';
import { AaaComponent } from './drawMap/botserve/botserve.component';
import { BbbComponent } from './drawMap/bot/bot.component';
//路由守衛
import { LoginGuard } from '../auth/login.guard';

const routes: Routes = [
    {
    path:'home',component:HomeComponent,
    
    canActivate:[LoginGuard], //應用
    
    children: [
          
            {path:'aaa', component: AaaComponent},
        {
            path: 'bbb', component: BbbComponent,
        },
        {path:'**',redirectTo: 'aaa'},
        ]
    }
   
];


@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule],
  
  providers:[LoginGuard] //匯入
})
export class HomeRouting { }

效果
在這裡插入圖片描述