成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

利用angular4和nodejs-express構(gòu)建簡單網(wǎng)站(十一)—HttpClient攔截器和

Eric / 2987人閱讀

摘要:攔截器的官方解釋為攔截機(jī)制是中的主要特性之一。使用這種攔截機(jī)制,你可以聲明一些攔截器,用它們監(jiān)視和轉(zhuǎn)換從應(yīng)用發(fā)送到服務(wù)器的請求。最后調(diào)用,以便這個(gè)請求流能走到下一個(gè)攔截器,并最終傳給后端處理器。

上一節(jié)介紹了好友模塊,這一節(jié)介紹和好友模塊中的控件有關(guān)的三個(gè)服務(wù)程序。

用HttpClient攔截器發(fā)送用戶認(rèn)證信息

在進(jìn)入好友模塊之前,需要向服務(wù)器發(fā)送認(rèn)證信息,在這里使用angular的HttpClient攔截器進(jìn)行發(fā)送。
攔截器的官方解釋為:HTTP 攔截機(jī)制是 @angular/common/http 中的主要特性之一。 使用這種攔截機(jī)制,你可以聲明一些攔截器,用它們監(jiān)視和轉(zhuǎn)換從應(yīng)用發(fā)送到服務(wù)器的 HTTP 請求。 攔截器還可以用監(jiān)視和轉(zhuǎn)換從服務(wù)器返回到本應(yīng)用的那些響應(yīng)。 多個(gè)選擇器會(huì)構(gòu)成一個(gè)“請求/響應(yīng)處理器”的雙向鏈表。如果想詳細(xì)了解攔截器,可以看官方文檔
我們利用攔截器在每次向服務(wù)器請求朋友列表時(shí)將認(rèn)證信息加入到頭部。
具體代碼如下:

import { Injectable } from "@angular/core";
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest } from "@angular/common/http";
import { Observable } from "rxjs/observable";
import { AuthTokenService } from "./authtoken.service";
@Injectable()
export class AuthInterceptor implements HttpInterceptor{
    constructor(
        private tokenServ: AuthTokenService
    ){}
    intercept(req: HttpRequest,next: HttpHandler) : Observable>{
        //獲取認(rèn)證信息
         const auth = this.tokenServ.getToken();
        //克隆request,加入新的頭信息
        const authReq = req.clone({headers:req.headers.set("Authorization", "Bearer " + auth)});
        return next.handle(authReq);
    }
}

要實(shí)現(xiàn)攔截器,就要實(shí)現(xiàn)一個(gè)實(shí)現(xiàn)了 HttpInterceptor 接口中的 intercept() 方法的類(AuthInterceptor)。在intercept()方法中先通過AuthTokenService的getToken()方法取得認(rèn)證信息。這些認(rèn)證信息是在登錄或注冊成功后由服務(wù)器發(fā)回來的jwt認(rèn)證信息。服務(wù)器如何發(fā)送這些信息請參考第三節(jié)的內(nèi)容,認(rèn)證信息的內(nèi)容是登錄或認(rèn)證的用戶ID。因?yàn)镠ttpRequest 實(shí)例的屬性卻是只讀(readonly)的,要修改請求信息只能先克隆它。在這里利用clone()方法在請求的頭部信息中加入認(rèn)證信息( clone() 方法的哈希型參數(shù)允許你在復(fù)制出克隆體的同時(shí)改變該請求的某些特定屬性)。最后調(diào)用 next.handle(),以便這個(gè)請求流能走到下一個(gè)攔截器,并最終傳給后端處理器。
最后還需要向模塊這個(gè)攔截器,這個(gè)AuthInterceptor攔截器就是一個(gè)由 Angular 依賴注入 (DI)系統(tǒng)管理的服務(wù),你必須在提供 HttpClient 的同一個(gè)(或其各級父注入器)注入器中提供這些攔截器。在好友模塊的providers中加入

 {
      provide: HTTP_INTERCEPTORS,
      useClass: AuthInterceptor,
      multi:true
  }

現(xiàn)在在好友模塊中每個(gè)發(fā)送到服務(wù)器的請求都會(huì)在頭部加上認(rèn)證信息。
補(bǔ)充內(nèi)容:服務(wù)器jwt認(rèn)證中間件
express的jwt中間件定義代碼如下:

var expressJwt = require("express-jwt");
//使用jwt攔截
app.use(expressJwt({
  secret: "secret"
}));
//處置jwt異常
app.use(function (err, req, res, next) {
  if (err.name === "UnauthorizedError") {
    res.status(401).send({
      "code": 401,
      "msg": "invalid token"
    });
  }
});
app.use("/friends", friends);

一定要把處理friends訪問的路由放到j(luò)wt中間件后面,不然jwt無法進(jìn)行驗(yàn)證。

利用路由守衛(wèi)保證未登錄用戶無法訪問好友信息

在上一節(jié)介紹路由時(shí),在路由配置中加入了canActivate: [AuthGuardService],這是angular路由守衛(wèi)服務(wù),路由守衛(wèi)的作用在官方文檔中的解釋如下:
現(xiàn)在,任何用戶都能在任何時(shí)候?qū)Ш降饺魏蔚胤健?但有時(shí)候這樣是不對的。
該用戶可能無權(quán)導(dǎo)航到目標(biāo)組件。
可能用戶得先登錄(認(rèn)證)。
在顯示目標(biāo)組件前,你可能得先獲取某些數(shù)據(jù)。
在離開組件前,你可能要先保存修改。
你可能要詢問用戶:你是否要放棄本次更改,而不用保存它們?
你可以往路由配置中添加守衛(wèi),來處理這些場景。

守衛(wèi)返回一個(gè)值,以控制路由器的行為:
如果它返回 true,導(dǎo)航過程會(huì)繼續(xù)
如果它返回 false,導(dǎo)航過程會(huì)終止,且用戶會(huì)留在原地。
在這里我們利用路由守衛(wèi)要求用戶先登錄才能導(dǎo)航到birthday模塊中的控件。
代碼如下:

import { Injectable } from "@angular/core";
import {
    CanActivate,
    ActivatedRouteSnapshot,
    RouterStateSnapshot,
    Router
} from "@angular/router";
import { UserService } from "./user.service";
import { AuthTokenService } from "./authtoken.service";
@Injectable()
export class AuthGuardService implements CanActivate {
    constructor(
        private tokenServe: AuthTokenService,
        private router: Router) { }
    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
        if (this.tokenServe.getToken() !== null) {
            return true;
        }
        this.router.navigate(["/login"]);
        return false;
    }
}

路由守衛(wèi)類也是一個(gè)注入服務(wù)類,它需要實(shí)現(xiàn)CanActivate接口的canActivate()方法。canActivate()方法實(shí)現(xiàn)了守衛(wèi)代碼。代碼很簡單,從AuthTokenService類的getToken()中獲取認(rèn)證信息的值,如果有就返回true,如果沒有就導(dǎo)航到登錄頁面。并返回false。
最后記住在birthday模塊中providers中加入AuthGuardService。

birthday.service數(shù)據(jù)提供服務(wù)介紹

BirthdayService類為birthday模塊提供了數(shù)據(jù)服務(wù),代碼如下:

import { Injectable } from "@angular/core";
import { HttpClient, HttpHeaders,HttpErrorResponse } from "@angular/common/http";
import { UserService } from "../user.service";

import "rxjs/add/operator/map";

export class Friend {
    constructor(
        public fid: number,
        public fname: string,
        public fbirth: Date,
        public fnumber: string,
        public femail: string,
        public fgroup: string,
        public state: string,
        public photo: string,
        public uid:number
    ) { }
}

@Injectable()
export class BirthdayService {
    constructor(
        private userServ: UserService,
        private http: HttpClient) {
    }
    //獲取全部朋友信息
    getFriends() {
        return this.http.get("http://localhost:3000/friends/friend-list",
            { observe: "response"});}
    //獲取單個(gè)朋友信息
    getFriend(id: number | string) {
        return this.getFriends().map(res => {
            if (res.body["code"] === "200") {
                return res.body["results"].find(result => result.fid === +id);}
        });
    }
    //修改朋友信息
    editFriend(friend: Friend){
        const body = {"value":friend,"operate":"edit"};
        return this.http.post("http://localhost:3000/friends/editfriend",body);
    }
    //新建朋友信息
    newFriend(friend: Friend){
        const body = {"value":friend,"operate":"new"};
        return this.http.post("http://localhost:3000/friends/editfriend", body);
    }
    //刪除好友
    deleteFriend(friend:Friend){
        const body = {"value":friend, "operate":"delete"};
        return this.http.post("http://localhost:3000/friends/editfriend",body);
    }
    //錯(cuò)誤處理
    handleError(err: HttpErrorResponse): string {
        if (err.error instanceof Error) {
            return "發(fā)生錯(cuò)誤,錯(cuò)誤信息:" + err.error.message;
        } else {
            console.log(`Backend returned code ${err.status}, body was: ${err.error["msg"]}`);
            return err.error["msg"];
        }
    }
}

首先在類外定義了一個(gè)Friend類,在這個(gè)類中定義了friend信息。BirthdayService類的主要功能有6部分:

獲取全部朋友信息。通過HttpClient的get方法發(fā)送獲取到全部的friend信息的請求。

獲取單個(gè)朋友信息。getFriends()方法返回的是一個(gè)Observable對象,利用Observable的map()函數(shù)的回調(diào)找到對應(yīng)id的單個(gè)friend對象,并繼續(xù)發(fā)射Observable對象。

修改朋友信息。將修改后的friend信息post到服務(wù)器。在發(fā)送的body中,除了修改后的friend對象,還發(fā)送了一個(gè)字符串屬性:"operate":"edit",用于區(qū)分是修改friend還是新建friend,這了的edit代表修改信息。(具體的服務(wù)器操作代碼將在下一章介紹)。

新建朋友信息。和修改friend信息同理,只不過將body中的"operate"改為"new"。

刪除好友。也和修改friend信息同理,只不過將body中的"operate"改為"delete"。

錯(cuò)誤處理。如果是客戶端(angular代碼)出了錯(cuò),會(huì)拋出一個(gè) Error 類型的異常,由此判斷如果錯(cuò)誤的類型是Error類型,就表示前端出錯(cuò),返回一條錯(cuò)誤信息:"發(fā)生錯(cuò)誤,錯(cuò)誤信息:" + err.error.message;。如果是后端出錯(cuò),就打印出錯(cuò)誤狀態(tài)和信息。

關(guān)于birthday模塊的服務(wù)程序就介紹完了。下一章將要介紹服務(wù)器端express框架如何處理這些請求。今天將我的代碼傳到了github上,方便大家參考。地址如下:
前端:https://github.com/db991400/b...
后端:https://github.com/db991400/b...

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/94572.html

相關(guān)文章

  • 利用angular4nodejs-express構(gòu)建一個(gè)簡單網(wǎng)站(五)—用戶的注冊登錄-Htt

    摘要:后臺注冊成功后,會(huì)返回狀態(tài)的認(rèn)證信息。后臺數(shù)據(jù)的處理,詳見利用和構(gòu)建一個(gè)簡單的網(wǎng)站三訪問。在這個(gè)方法中分別針對這兩種錯(cuò)誤進(jìn)行處理。 上一節(jié)簡單介紹了一下利用angular構(gòu)建的主路由模塊,根據(jù)上一節(jié)的介紹,主頁面加載時(shí)直接跳轉(zhuǎn)到用戶管理界面,下面就來介紹一下用戶管理模塊。啟動(dòng)應(yīng)用后,初始界面應(yīng)該是這樣的: showImg(https://segmentfault.com/img/bV3...

    Lin_R 評論0 收藏0
  • 利用angular4nodejs-express構(gòu)建一個(gè)簡單網(wǎng)站(五)—用戶的注冊登錄-Htt

    摘要:后臺注冊成功后,會(huì)返回狀態(tài)的認(rèn)證信息。后臺數(shù)據(jù)的處理,詳見利用和構(gòu)建一個(gè)簡單的網(wǎng)站三訪問。在這個(gè)方法中分別針對這兩種錯(cuò)誤進(jìn)行處理。 上一節(jié)簡單介紹了一下利用angular構(gòu)建的主路由模塊,根據(jù)上一節(jié)的介紹,主頁面加載時(shí)直接跳轉(zhuǎn)到用戶管理界面,下面就來介紹一下用戶管理模塊。啟動(dòng)應(yīng)用后,初始界面應(yīng)該是這樣的: showImg(https://segmentfault.com/img/bV3...

    feng409 評論0 收藏0
  • 利用angular4nodejs-express構(gòu)建一個(gè)簡單網(wǎng)站(八)—注冊之保存用戶數(shù)據(jù)

    摘要:上一章通過用戶注冊講解了響應(yīng)式表單,這章主要講解如何向服務(wù)器提交注冊數(shù)據(jù)并導(dǎo)航到好友信息模塊。利用的方法將這個(gè)憑證存儲(chǔ)到本地。針對一個(gè)進(jìn)行數(shù)據(jù)存儲(chǔ)。當(dāng)用戶關(guān)閉瀏覽器窗口后,數(shù)據(jù)會(huì)被刪除。 上一章通過用戶注冊講解了響應(yīng)式表單ReactiveForm,這章主要講解如何向服務(wù)器提交注冊數(shù)據(jù)并導(dǎo)航到好友信息模塊。 提交注冊信息 向服務(wù)器提交信息是通過模板中標(biāo)簽中的(ngSubmit)=onSu...

    haobowd 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<