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 { }
效果