国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

使用service實(shí)現(xiàn)登錄、權(quán)限控制

Aomine / 1329人閱讀

摘要:就沒必要?jiǎng)优5叮瑒?chuàng)建一個(gè)數(shù)據(jù)庫了執(zhí)行完后,在目錄下創(chuàng)建一個(gè)程序,自動(dòng)植入到當(dāng)前項(xiàng)目中,訪問的和與訪問域名端口一致。就沒必要?jiǎng)优5叮瑒?chuàng)建一個(gè)數(shù)據(jù)庫了本篇博文將為你介紹如何使用實(shí)現(xiàn)權(quán)限控制,我會(huì)創(chuàng)建一個(gè)簡單的登錄示例加以說明。

文章來源:http://blog.ddlisting.com

官網(wǎng)對于登錄、用戶權(quán)限的介紹只有一段簡單的說明,并沒有詳細(xì)說明如何使用service實(shí)現(xiàn)權(quán)限控制。下面地址是官網(wǎng)的說法:

https://guides.emberjs.com/v2.6.0/applications/services/

An Ember.Service is a long-lived Ember object that can be made available in different parts of your application.
Services are useful for features that require shared state or persistent connections. Example uses of services might include:

User/session authentication.

Geolocation.

WebSockets.

Server-sent events or notifications.

Server-backed API calls that may not fit Ember Data.

Third-party APIs.

Logging.

service是啥東西呢?簡單講service也是一個(gè)Ember.Object只不過這個(gè)對象與普通的對象有點(diǎn)不一樣。首先這種對象是放在文件夾appName/app/services目錄下。其次放在這個(gè)目錄下的對象Ember會(huì)自動(dòng)注冊(registered)或者注入(injection)到Ember項(xiàng)目中。這種對象有如下2個(gè)特點(diǎn)

對象聲明周期是session級別的

在Ember項(xiàng)目的任何地方都可以調(diào)用

正是基于這兩個(gè)特性才能實(shí)現(xiàn)權(quán)限的控制。最簡單的例子就是用戶的登錄問題。目前也有現(xiàn)成的插件實(shí)現(xiàn)權(quán)限的控制,請看使用ember-simple-auth實(shí)現(xiàn)Ember.js應(yīng)用的權(quán)限控制所描述的方法,但是如果要根據(jù)自己項(xiàng)目需要去實(shí)現(xiàn)權(quán)限控制那么又如何做呢?

本篇博文將為你介紹如何使用service實(shí)現(xiàn)權(quán)限控制,我會(huì)創(chuàng)建一個(gè)簡單的登錄示例加以說明。如有不妥歡迎留言指正。

構(gòu)建項(xiàng)目
ember new secretcodez
cd secretcodez
ember s

驗(yàn)證項(xiàng)目是否創(chuàng)建成功http://localhost:4200。看到Welcome to Ember說明項(xiàng)創(chuàng)建成功。下面創(chuàng)建演示所需文件。

創(chuàng)建文件
ember g route secret
ember g route login
ember g route application

ember g component secret-page
ember g component login-page

ember g model code description:string

ember g adapter application

項(xiàng)目演示用到的文件基本就這些。

secret頁面
{{! app/templates/secret.hbs }}
{{secret-page model=model}}
{{! app/tempalates/components/secret-page.hbs}}

secret page

    {{#each model as |code|}}
  • {{code.description}}
  • {{/each}}
后端服務(wù)

為了測試創(chuàng)建一個(gè)簡單的后端服務(wù)程序,使用的是Node,然后寫死一些測試數(shù)據(jù)。就沒必要?jiǎng)优5叮瑒?chuàng)建一個(gè)數(shù)據(jù)庫了!

ember g server
npm install
npm install body-parser --save-dev

執(zhí)行完ember g server后,在APP目錄下創(chuàng)建一個(gè)nodejs程序,自動(dòng)植入到當(dāng)前項(xiàng)目中,訪問的domain和port與ember訪問域名端口一致。

打開index.js編輯后端請求監(jiān)聽。

// server/index.js

const bodyParser = require("body-parser");

module.exports = function(app) {

  app.use(bodyParser.urlencoded({ extended: true }));

  app.get("/api/codes", function (req, res) {    
    return res.status(200).send({
          codes: [
              { id:1, description: "為了測試創(chuàng)建一個(gè)簡單的后端服務(wù)程序,使用的是Node,然后寫死一些測試數(shù)據(jù)。就沒必要?jiǎng)优5叮瑒?chuàng)建一個(gè)數(shù)據(jù)庫了!" },
              { id:2, description: "本篇博文將為你介紹如何使用service實(shí)現(xiàn)權(quán)限控制,我會(huì)創(chuàng)建一個(gè)簡單的登錄示例加以說明。如有不妥歡迎留言指正。" }
          ]
      });
  });

};

既然用到自己的后端服務(wù)那么對應(yīng)的你就需要自定義適配器了。簡單起見就創(chuàng)建RESTAdapter適配器吧。JSONAPIAdapter適配器相對麻煩點(diǎn),需要格式化數(shù)據(jù)為json api。

// app/adapters/application.js

export default DS.RESTAdapter.extend({
  namespace: "api"
});

使用屬性namespace指定URL前綴,比如請求URL為http://localhost:4200/api/codes,自動(dòng)在請求上加入前綴api

修改路由,獲取后端數(shù)據(jù)。

// app/routes/secret.js

export default Ember.Route.extend({
  model() {
    // 返回后端數(shù)據(jù),這些數(shù)據(jù)直接從 server/index.js 獲取
    return this.store.findAll("code");
  }
});

重新啟動(dòng)項(xiàng)目。檢查項(xiàng)目是否有錯(cuò)誤!如果啟動(dòng)沒問題,那么訪問http://localhost:4200/secret你也會(huì)得到如下截圖的效果。

從截圖中可以看到發(fā)送一個(gè)請求http://localhost:4200/api/codes,并且從這個(gè)請求中獲取到服務(wù)端返回的數(shù)據(jù)。你可以直接把這個(gè)URL放到瀏覽器地址欄執(zhí)行,可以清楚的看到返回的數(shù)據(jù)。數(shù)據(jù)的格式是普通的json格式。

目前的效果是任何人都可以訪問,還沒實(shí)現(xiàn)權(quán)限控制的效果。那么如何去實(shí)現(xiàn)呢?不知道你是否看過前面的文章adapter與serializer使用示例,如果你看過里面有介紹過在請求頭加驗(yàn)證信息這個(gè)小結(jié)。如果我也想這么實(shí)現(xiàn)控制訪問API的權(quán)限如何做呢?

修改服務(wù)端,加入權(quán)限校驗(yàn)
// 攔截 /api/codes 請求
app.get("/api/codes", function(req, res) {
    //獲取數(shù)據(jù)之前先校驗(yàn)請求者是否有權(quán)訪問資源
    //  做一個(gè)非常簡單的判斷,如果請求的頭信息不等于BLOG.DDLISTING.COM則認(rèn)為無權(quán)限
    if (req.headers["authorization"] !== "BLOG.DDLISTING.COM") {
        return res.status(403).send("您無權(quán)訪問此資源!")
    }
    // 直接返回正確狀態(tài)和測試數(shù)據(jù)
    return res.status(200).send({
        codes: [
            { id:1, description: "為了測試創(chuàng)建一個(gè)簡單的后端服務(wù)程序,使用的是Node,然后寫死一些測試數(shù)據(jù)。就沒必要?jiǎng)优5叮瑒?chuàng)建一個(gè)數(shù)據(jù)庫了!" },
            { id:2, description: "本篇博文將為你介紹如何使用service實(shí)現(xiàn)權(quán)限控制,我會(huì)創(chuàng)建一個(gè)簡單的登錄示例加以說明。如有不妥歡迎留言指正。" }
        ]
    });
})

注意:_代碼只列出主要部分,其他的不變。_
在代碼中加入了簡單的權(quán)限校驗(yàn),通常authorization的值應(yīng)該是變化的或者是每個(gè)用戶都是唯一的,比如oauth2中的access token。當(dāng)你再次訪問之前的資源http://localhost:4200/secret可以看到,報(bào)錯(cuò)了,提示無權(quán)訪問。如下截圖:

顯然這樣的校驗(yàn)是沒啥意義的,那么如果你也想模擬Oauth2也生成一個(gè)唯一的access token,你可以請求之前首先獲取一個(gè)access token。但是這個(gè)access token不是隨便就能獲取的,需要通過登錄成功后才能獲取到。下面加入模擬登錄的程序。仍然是修改server/index.js

// 登錄
app.post("/api/login", function(req, res) {
    //判斷用戶名和密碼是否正確,這里就直接判斷字符串了,實(shí)際中通常是通過查詢數(shù)據(jù)去判斷登錄的用戶是否存在
    if (req.body.username === "blog.ddlisting.com"
      && req.body.password === "yes") {
          res.send({ access_token: "BLOG.DDLISTING.COM" });
      } else {
          res.status(400).send({ error: "獲取token錯(cuò)誤!" });
      }
});

有了后端的服務(wù)之后顯然我們需要在前端增加一個(gè)登錄的表單,提供用戶登錄并且登錄成功之后還要把獲取到的access_token保存好,在發(fā)送請求的時(shí)候設(shè)置到請求的頭。這個(gè)時(shí)候就需要用到service了!!

登錄 登錄表單
{{! app/templates/login.hbs 登錄}}
{{login-page}}
{{! app/templates/components/login-page.hbs 登錄表單}}

{{link-to "點(diǎn)擊查看有權(quán)才能訪問的資源" ’secret}}

登錄

默認(rèn)的用戶名和密碼為:blog.ddlisting.com/yes

{{input type="text" value=username placeholder="blog.ddlisting.com"}} {{input type="password" value=password placeholder="密碼"}}
登錄處理

在組件類中添加處理登錄的action。

// app/components/login-page.js

import Ember from "ember";

export default Ember.Component.extend({
    authManager: Ember.inject.service(),  //注入servi"auth-manager"ce
    actions: {
        authenticate() {
            const { username, password } = this.getProperties("username", "password");
            //調(diào)用service類中的authenticate方法校驗(yàn)登錄的用戶
            this.get("authManager").authenticate(username, password),then(() => {
                console.log("登錄成功");
            }, (err) => {
                console.log("登錄失敗");
            });
        }
    }
});

在這個(gè)類中使用了service類,并且調(diào)用此類中的authenticate方法。代碼中的屬性authManager就是一個(gè)service實(shí)例。下面定義service類。

ember g service auth-manager
// app/serivces/auth-manager.js

import Ember from "ember";

export default Ember.Service.extend({
    accessToken: null,

    // 判斷accessToken是否是空
    isAuthenticated: Ember.computed.bool("accessToken"),

    // 發(fā)起請求校驗(yàn)登錄用戶
    authenticate(username, password) {
        return Ember.$.ajax({
            method: "post",
            url: "/api/login",
            data: { username: username, password: password }
        }).then((res) => {
            // 設(shè)置返回的access_token到service類的屬性中
            this.set("accessToken", res.access_token);
        }, (err) => {
            //登錄失敗
        });
    },
    invalidate() {
        this.set("accessToken", null);
    }
});

在組件類login-page.js中并沒有直接發(fā)請求校驗(yàn)用戶是否登錄成功,而是通過調(diào)用serivce類的方法去校驗(yàn),目的是為了把返回的值保存到service的屬性中,這也是利用它的特性。方法invalidate的目的是執(zhí)行退出登錄操作,把保存到service屬性中的值置空,使得計(jì)算屬性isAuthenticated返回false

一切都定義好了下面就是如何使用這個(gè)service屬性了!修改適配器的代碼,在請求頭中加入accessToken

// import JSONAPIAdapter from "ember-data/adapters/json-api";
import DS from "ember-data";

// 不使用默認(rèn)適配器JSONAPIAdapter,而是使用RESTAdapter
export default DS.RESTAdapter.extend({
    namespace: "api",  //訪問請求前綴: http://localhost:4200/api/codes
    // 加入請求頭
    authManager: Ember.inject.service("auth-manager"),
    headers: Ember.computed("authManager.accessToken", function() {
        //動(dòng)態(tài)返回accessToken的值
        return {
            "authorization": `${this.get("authManager.accessToken")}`
        };
    })
});

到此代碼基本寫完了,為了處理服務(wù)端返回的錯(cuò)誤直接在application路由中攔截error事件,在這個(gè)事件中處理錯(cuò)誤的情況。
說明:所有的子路由的error事件都會(huì)自動(dòng)冒泡到路由applicationerror事件中。

// app/routes/application.js
import Ember from "ember";

export default Ember.Route.extend({
    actions: {
        // 處理所有的error事件
        error(reason, transition) {
            //如果出現(xiàn)錯(cuò)誤直接轉(zhuǎn)到登錄界面
            this.transitionTo("login");
            return false;
        }
    }
});

項(xiàng)目重啟完畢(是手動(dòng)終止在啟動(dòng),否則會(huì)出現(xiàn)service未定義的情況)之后可以看到界面直接跳轉(zhuǎn)到了登錄頁面,實(shí)現(xiàn)了簡單的權(quán)限攔截(無權(quán)先登錄)。

未登錄直接點(diǎn)擊鏈接“點(diǎn)擊查看有權(quán)才能訪問的資源”效果

可以看到瀏覽器控制臺(tái)打印信息顯示資源無權(quán)訪問,返回的代碼是403

輸入錯(cuò)誤的用戶名或密碼的情況:

登錄成功再訪問授權(quán)資源

登錄成功之后再點(diǎn)擊鏈接可以正常訪問了,并且正確看到后端返回的數(shù)據(jù)。

即使你點(diǎn)擊鏈接“點(diǎn)擊查看有權(quán)才能訪問的資源”也還是會(huì)跳轉(zhuǎn)回登錄頁面。那么開始測試登錄后的效果,在表單中輸入正確的用戶名和密碼。點(diǎn)擊登錄后跳轉(zhuǎn)到了

退出

有登錄就會(huì)有退出,退出相對簡單,只要銷毀了service類中的屬性accessToken值即可。

{{! app/tempalates/components/secret-page.hbs}}

secret page

    {{#each model as |code|}}
  • {{code.description}}
  • {{/each}}


// app/components/secret-page.js
import Ember from "ember";

export default Ember.Component.extend({
    //注入service
    authManager: Ember.inject.service("auth-manager"),

    actions: {
        invalidate() {
            this.get("authManager").invalidate();  //退出登錄狀態(tài)
            //暫時(shí)粗暴處理,直接強(qiáng)制刷新,重新進(jìn)入application路由觸發(fā)error事件,再次判斷是否登錄
            location.reload();
        }
    }
});

對于退出事件的處理就比較簡單粗暴了,直接刷新頁面,由于屬性authManager的值已經(jīng)設(shè)置為null所以發(fā)起請求的時(shí)候是無權(quán)限的會(huì)再次觸發(fā)error事件,然后跳轉(zhuǎn)到登錄頁面。

到這里,基本上實(shí)現(xiàn)了一個(gè)簡單的權(quán)限控制功能。例子比較簡單,但是處理的思路大體上是這樣做的,能實(shí)現(xiàn)這樣的功能是基于service類的特性。也希望讀者能通過本例理解懂得如何使用service

項(xiàng)目代碼:https://github.com/ubuntuvim/secretcodez,有疑問歡迎給我留言。
您的支持是我繼續(xù)寫作的最大動(dòng)力,謝謝!!

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

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/79664.html

相關(guān)文章

  • 手摸手,帶你用vue擼后臺(tái) 系列二(登錄權(quán)限篇)

    摘要:我們將登錄按鈕上綁上事件,點(diǎn)擊登錄之后向服務(wù)端提交賬號和密碼進(jìn)行驗(yàn)證。所以前端和后端權(quán)限的劃分是不太一致。側(cè)邊欄最后一個(gè)涉及到權(quán)限的地方就是側(cè)邊欄,不過在前 完整項(xiàng)目地址:vue-element-admin 系列文章: 手摸手,帶你用vue擼后臺(tái) 系列一(基礎(chǔ)篇) 手摸手,帶你用vue擼后臺(tái) 系列二(登錄權(quán)限篇) 手摸手,帶你用vue擼后臺(tái) 系列三 (實(shí)戰(zhàn)篇) 手摸手,帶你用vu...

    不知名網(wǎng)友 評論0 收藏0
  • [開源作品] skadmin 管理系統(tǒng)

    摘要:簡介項(xiàng)目基于的前后端分離的管理系統(tǒng),項(xiàng)目采用分模塊開發(fā)方式,權(quán)限控制采用,基于角色的訪問控制,支持?jǐn)?shù)據(jù)字典數(shù)據(jù)權(quán)限管理前端菜單支持動(dòng)態(tài)路由,另外還有其他的功能模塊日志管理代碼生成器系統(tǒng)監(jiān)控云存儲(chǔ)管理系統(tǒng)工具等等。 簡介 項(xiàng)目基于 Spring Boot 2.1.0 、 Spring Data JPA、 Spring Security、Redis、Vue的前后端分離的管理系統(tǒng),項(xiàng)目采用分...

    codergarden 評論0 收藏0
  • vue中如何實(shí)現(xiàn)后臺(tái)管理系統(tǒng)的權(quán)限控制

    摘要:二接口訪問的權(quán)限控制接口權(quán)限就是對用戶的校驗(yàn)。代碼如下按扭權(quán)限指令至此為止,權(quán)限控制流程就已經(jīng)完全結(jié)束了,在最后我們再看一下完整的權(quán)限控制流程圖吧五路由控制完整流程圖六參考文獻(xiàn)手?jǐn)]后臺(tái)管理網(wǎng)站之權(quán)限控制手摸手,帶你用擼后臺(tái)之權(quán)限控制 原文首發(fā)于我的博客,歡迎點(diǎn)擊查看獲得更好的閱讀體驗(yàn)~ 一、前言 在廣告機(jī)項(xiàng)目中,角色的權(quán)限管理是卡了挺久的一個(gè)難點(diǎn)。首先我們確定的權(quán)限控制分為兩大部分,其...

    songze 評論0 收藏0
  • vue中如何實(shí)現(xiàn)后臺(tái)管理系統(tǒng)的權(quán)限控制

    摘要:二接口訪問的權(quán)限控制接口權(quán)限就是對用戶的校驗(yàn)。代碼如下按扭權(quán)限指令至此為止,權(quán)限控制流程就已經(jīng)完全結(jié)束了,在最后我們再看一下完整的權(quán)限控制流程圖吧五路由控制完整流程圖六參考文獻(xiàn)手?jǐn)]后臺(tái)管理網(wǎng)站之權(quán)限控制手摸手,帶你用擼后臺(tái)之權(quán)限控制 原文首發(fā)于我的博客,歡迎點(diǎn)擊查看獲得更好的閱讀體驗(yàn)~ 一、前言 在廣告機(jī)項(xiàng)目中,角色的權(quán)限管理是卡了挺久的一個(gè)難點(diǎn)。首先我們確定的權(quán)限控制分為兩大部分,其...

    iliyaku 評論0 收藏0
  • vue中如何實(shí)現(xiàn)后臺(tái)管理系統(tǒng)的權(quán)限控制

    摘要:二接口訪問的權(quán)限控制接口權(quán)限就是對用戶的校驗(yàn)。代碼如下按扭權(quán)限指令至此為止,權(quán)限控制流程就已經(jīng)完全結(jié)束了,在最后我們再看一下完整的權(quán)限控制流程圖吧五路由控制完整流程圖六參考文獻(xiàn)手?jǐn)]后臺(tái)管理網(wǎng)站之權(quán)限控制手摸手,帶你用擼后臺(tái)之權(quán)限控制 原文首發(fā)于我的博客,歡迎點(diǎn)擊查看獲得更好的閱讀體驗(yàn)~ 一、前言 在廣告機(jī)項(xiàng)目中,角色的權(quán)限管理是卡了挺久的一個(gè)難點(diǎn)。首先我們確定的權(quán)限控制分為兩大部分,其...

    VincentFF 評論0 收藏0

發(fā)表評論

0條評論

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