资讯专栏INFORMATION COLUMN

使用 ember-simple-auth 实现 Ember.js 应用的权限控制

joyqi / 961人阅读

摘要:很多网站都有登录功能,对于的应用我们怎么实现权限的控制呢本篇将为你演示一个最常用的权限控制例子用户登录。升级后使用的版本是。修改这两个文件后执行命令升级。到目前为止我们还没使用过任何有关插件的内容。目前官方提供了三种常用的验证器。

很多网站都有登录功能,对于Ember的应用我们怎么实现权限的控制呢?本篇将为你演示一个最常用的权限控制例子:用户登录。

要实现登录最常用的方式是通过判断session值,如果session中存在你所需要的值则可以认为是用户是经过了登录并且把用户信息设置到session了,如果session中没有用户信息则认为用户没有登录,直接跳转到登录或者注册页面。

本篇会引入一个专门用于控制权限的插件ember-simple-auth,文章中大部分代码是直接参考这个插件的文档所写。如果你需要项目的代码请移步github下载。

好了,废话少说,直接放码出来吧。

创建Ember应用

本文会使用Ember CLI名称创建项目和项目所需的文件,更多有关Ember CLI的命令请自行到官网学习。

ember new chapter8_simple_auth
cd chapter8_simple_auth
ember server

如果你的项目搭建成功执行http://localhost:4200,会看到Welcome to Ember,说明项目搭建成功。

升级Ember、Jquery版本

本项目会升级Ember版本,目前(_2015-11-18_)来说如果是使用Ember CLI命令安装的项目Ember的版本是1.13.7。升级后使用的版本是2.0.0-beta.3

升级步骤:

修改bower.json
修改后此文件主要的代码如下:

{
  "dependencies": {
    "ember": "2.0.0-beta.3"
  },
      "resolutions": {
      "ember": "2.0.0-beta.3"
  }
}

删除原有的Ember
必须要手动删除原有的版本,否则因为缓存的问题使用命令重新安装的时候可能安装不成功。手动删除如下目录:appName/bower_components/ember

安装新版本Ember
使用命令:bower install,重新安装Ember。

检查是否安装成功。
打开appName/bower_components/ember/ember.js,可以看到Ember是那个版本。如果是2.0.0-beta.3说明升级成功。

同样的方式升级Jquery
如果你升级不成功,你可以参考我的项目的bower.json、package.json升级。修改这两个文件后执行命令bower install升级。

重启项目
可以看到浏览器控制台打印出Ember的版本信息。

2015-11-18 23:54:08.902 ember.debug.js:5202 DEBUG: -------------------------------
2015-11-18 23:54:08.916 ember.debug.js:5202 DEBUG: Ember             : 2.0.0-beta.3
2015-11-18 23:54:08.916 ember.debug.js:5202 DEBUG: jQuery            : 2.1.4
2015-11-18 23:54:08.917 ember.debug.js:5202 DEBUG: -------------------------------

到此项目的升级工作完成。

安装插件ember-simple-auth

直接使用npm命令安装,安装的方法可以参考官方教程,直接在项目目录下运行ember install ember-simple-auth即可完成安装。可以在appName/bower_components看到安装的插件。

项目主要代码文件 首页模板文件
{{! app/templates/application.hbs }}

This is my first auth proj

{{#if session.isAuthenticated}}

Logout

{{else}}

Login

{{/if}} {{outlet}}

session.isAuthenticated是插件ember-simple-auth封装好的属性,如果没有登录isAuthenticated为false,sessionRequiresAuthentication也是插件ember-simple-auth提供的方法。此方法会自动根据用户实现的authenticate方法校验用户是否已经登录(isAuthenticatedtrue)。

定义登录、登录成功组件

使用Ember CLI创建两个组件:login-formget-quotes

ember g component login-form
ember g component get-quotes

分别编写这两个组件和组件对应的模板文件。

login-form.js

// app/components/login-form.js

import Ember from "ember";

export default Ember.Component.extend({
    // authenticator: "authenticator: custom",

    actions: {
        authenticate: function() {
            var user = this.getProperties("identification", "password");
            this.get("session").authenticate("authenticator:custom", user).catch((msg) => {
                this.set("errorMessage", msg);
            });
        }
    }
});

其中authenticator属性执行了一个自定义的身份验证器customidentificationpassword是页面输入的用户名和密码。

getProperties方法会自动获取属性值并自动组装成hash形式({key: value}形式)。msg是方法authenticate验证不通过的提示信息。

在此简单处理,直接放回到界面显示。

login-form.hbs

{{! app/templates/login-form.hbs }}

{{input value=identification placeholder="enter your name" class="form-control"}}
{{input value=password placeholder="enter password" class="form-control" type="password"}}
{{#if errorMessage}}
Login failed: {{errorMessage}}
{{/if}}

这个文件比较简单没什么好说,errorMessage就是组件类中返回的提示信息。

get-quotes.js

// app/components/get-quotes.js

import Ember from "ember";

export default Ember.Component.extend({
    gotQuote: false,
    quote: "",

    actions: {
        getQuote: function() {
            var that = this;
            //  返回一个随机的字符串
            Ember.$.ajax({
                type: "GET",
                // url: "http://localhost:3001/api/protected/random-quote",
                url: "http://localhost:3001/api/random-quote",
                success: function(response) {
                    that.setProperties({ quote: response, gotQuote: true });
                },
                error: function(error) {
                    alert("An error occurred while processing the response.");
                    console.log(error);
                }
            });
        }
    }
});

此组件模拟登陆之后才能访问的资源,通过Ajax获取一个随机的字符串。
请求的服务代码你也可以从github上下载,下载之后按照文档安装,直接运行node server.js既可,服务器端是一个nodejs程序,如果你的电脑没有安装nodejs,请自行下载安装。

登陆、信息显示页面

这两个页面比较简单,直接调用组件。为什么我没有直接把组件代码放在这两个页面呢??我们知道Ember2.0之后官方不推荐使用控制器,控制器的作用在弱化,组件变得越来越重要。

既然我们项目使用的是Ember2.0版本那就必须要用组件去替代控制器实现某些逻辑的判断。

{{! app/templates/login.hbs }}

{{login-form}}
{{! app/templates/protected.hbs }}

{{get-quotes}}
登陆前的提示信息

我们直接把登陆使用的用户名和密码提示出来,为了测试方便嘛,再者项目还没有注册功能。

{{! app/templates/index.hbs }}

{{#unless session.isAuthenticated}}
    
You can {{#link-to "login" className="alert-link"}}log in {{/link-to}} with login ember and password 123.
{{/unless}}

但是用户名和密码为什么是ember123呢??你看到服务器代码里的user-routes.js就明白了,github上用的是gonto,我下载之后做了点小修改。你可以修改成你喜欢的字符串。

到此常规的文件就创建完成了,下面的内容才是重头戏。到目前为止我们还没使用过任何有关插件ember-simple-auth的内容。

路由配置
ember g route login
ember g route protected
ember g route application

执行命令的时候要注意别把之前的模板覆盖了!!!下面是这几个文件的内容。

application.js

// app/routes/application.js

import Ember from "ember";

import ApplicationRouteMixin from "simple-auth/mixins/application-route-mixin";

export default Ember.Route.extend(ApplicationRouteMixin, {
    actions: {
        invalidateSession: function() {
            this.get("session").invalidate();
        }
    }
});

这个类首先混合了ApplicationRouteMixin类的特性,然后再加上自定义的特性。注意第二行代码,引入了插件ember-simple-auth的类ApplicationRouteMixin。更多有关这个类的介绍请点击链接查看。session是插件内置的属性。方法invalidate设置session为无效或者说是当前认证无效,更多详细信息请看方法的API介绍。

protected.js

// app/routes/protected.js

import Ember from "ember";

import AuthenticatedRouteMixin from "simple-auth/mixins/authenticated-route-mixin";

// 实现AuthenticatedRouteMixin的类会自动根据权限过滤,如果经过登录页面直接进入这个route会自动跳转到登录页面
export default Ember.Route.extend(AuthenticatedRouteMixin, {
});

此类也是引入插件ember-simple-auth封装好的类AuthenticatedRouteMixin。混合了此类的类会自动根据权限过滤,如果没有通过认证而直接访问这个route会被强制跳转到登录页面。

login.js

// app/routes/login.js

import Ember from "ember";

export default Ember.Route.extend({
    //  清空提示信息
    setupController: function(controller, model) {
        console.log("route:login model = " + model);
        controller.set("errorMessage", null);
    }
});

这个route的作用是清空页面的提示信息,如果不清空你再次进入的时候还是会看到提示信息。

控制器配置

路由protected之所以能实现无权限重定向到登录页面是因为在controller:login中指定了登录处理类。

login.js

// app/controllers/login.js

import Ember from "ember";

import LoginControllerMixin from "simple-auth/mixins/login-controller-mixin";

export default Ember.Controller.extend(LoginControllerMixin, {
});

此类引入插件封装好的登录处理类LoginControllerMixin,遗憾的是在插件目录下并没有发现这个类,看不到里面的实现!

核心处理类

最后的这两个类是整个项目最核心的东西——自定义校验器、授权者。

授权者类 authorizer/custom.js

// app/authenrizers/custom.js

import Ember from "ember";
import Base from "simple-auth/authorizers/base";

export default Base.extend({
    authorize: function(jqXHR, requestOptions) {
        var accessToken = this.get("session.content.secure.token");
        if (this.get("session.isAuthenticated") && !Ember.isEmpty(accessToken)) {
            //  setRequestHeader方法自定义请求头信息:键为Authorization,值为Ember+accessToken
            // 有关这个方法的介绍请看[API介绍](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/setRequestHeader)
            jqXHR.setRequestHeader("Authorization", "Ember" + accessToken);
        }
    }
});

直接继承Base类,重新实现authorize方法。或者你亦可以像github上的教程使用插件已经定义好的类。
authorize方法第一个参数是需要设置的session数据,第二个参数是一个回调函数,更多详情情况接口API。

验证器类 authenticators/custom.js

//  app/authenticators/custom.js

import Ember from "ember";
import Base from "simple-auth/authenticators/base";

export default Base.extend({
    tokenEndpoint: "http://localhost:3001/sessions/create",
    restore: function(data) {
        return new Ember.RSVP.Promise(function(resolve, reject) {
            if (!Ember.isEmpty(data.token)) {
                resolve(data);
            } else {
                reject();
            }
        });
    },
    authenticate: function(options) {
        return new Ember.RSVP.Promise((resolve, reject) => {
            Ember.$.ajax({
                url: this.tokenEndpoint,
                type: "POST",
                data: JSON.stringify({
                    username: options.identification,
                    password: options.password
                }),
                contentType: "application/json;charset=utf-8",
                dataType: "json"
            }).then(function(response) {
                Ember.run(function() {
                    resolve({
                        token: response.id_token
                    });
                });
            }, function(xhr, status, error) {
                var response = xhr.responseText;
                Ember.run(function() {
                    reject(response);
                });
            });
        });
    },
    invalidate: function() {
        console.log("invalidate...");
        return Ember.RSVP.resolve();
    }
});

这个类代码比较多,也比较复杂。目前官方提供了三种常用的验证器。

但是本项目使用的自定义的验证器。需要注意的是自定义的验证器需要实现restoreauthenticateinvalidate这个三个方法,最后一个方法不强制要求重写,但是前面两个方法必须重写。从代码实现可以看到这几个方法都返回了Promise对象。

代码首先是执行了Ajax请求http://localhost:3001/sessions/create,如果执行成功则返回token,否则返回出错信息,返回的错误信息可以在user-routes.js上看到,下载代码后你可以修改成自己喜欢的提示信息。

修改项目配置

到此项目的主要代码都已实现了,下面为了项目能正常运行还需要修改项目的配置文件config/environment.js

/* jshint node: true */

module.exports = function(environment) {
  var ENV = {
    // ……与原文件一样
    APP: {
      // Here you can pass flags/options to your application instance
      // when it is created
    },
    contentSecurityPolicy: {
        "default-src": ""none"",
        "script-src": ""self"",
        "font-src": ""self" *",
        "connect-src": ""self" *", // Allow data (ajax/websocket) from http://localhost:3001
        "img-src": ""self"",
        "style-src": ""self" "unsafe-inline" *", // Allow inline styles
        "media-src": ""self""
    }
  };
  ENV["simple-auth"] = {
        store: "simple-auth-session-store:local-storage",
        authorizer: "authorizer:custom",
        crossOriginWhitelist: ["http://localhost:3001/"],  // Ajax跨域设置
        // routeAfterAuthentication: "/",  //登录成功后跳转到的页面
        authenticationRoute: "login"  //  登录不成功转回登录页面
  };
  // ……与原文件一样

  return ENV;
};

没有列出的代码与默认生成的代码是一致的。

最后重启项目测试效果。

首先我们直接访问 http://localhost:4200/protected,可以看到直接被重定向到http://localhost:4200/login(前提是你还没登陆过)。然后再访问 http://localhost:4200 进入到项目首页。可以看到提示登陆的用户名和密码。然后点击login转到登陆界面。

下面是演示效果

没有输入用户、密码
如果没有输入用户名或者密码其中之一,或者都不输入就点击login,会出现如图提示信息。你也可以看浏览器控制台打印的日志信息,可以看到返回的状态码为400,这个状态码也是在user-routes.js中设置的。

用户名和密码不匹配

登陆成功的情况

可以看到浏览器URL转到http://localhost:4200/protected。然后点击按钮"Get Random quote",可以看到返回随机的字符串。

每点击一次就发送一次请求http://localhost:3001/api/random-quote,请求返回一个随机的字符串。

到此,使用插件ember-simple-auth实现ember应用的权限控制的内容全部结束完毕,各位读者们不知道你们是否看得明白,如果觉得文章将不对的地方欢迎给我留言,如果你觉得作者大半夜写文章精神可嘉也欢迎给我点个赞吧 =_=!!

参考文章

https://github.com/simplabs/ember-simple-auth

http://ember-simple-auth.com/api/index.html

http://www.programwitherik.com/ember-simple-auth-torii-example-application/

https://auth0.com/blog/2015/06/26/auth0-ember-simple-auth/

如果发现连接无法访问,那么你可能需要fanqiang

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/79561.html

相关文章

  • 使用service实现登录、权限控制

    摘要:就没必要动牛刀,创建一个数据库了执行完后,在目录下创建一个程序,自动植入到当前项目中,访问的和与访问域名端口一致。就没必要动牛刀,创建一个数据库了本篇博文将为你介绍如何使用实现权限控制,我会创建一个简单的登录示例加以说明。 文章来源:http://blog.ddlisting.com 官网对于登录、用户权限的介绍只有一段简单的说明,并没有详细说明如何使用service实现权限控制。下面...

    Aomine 评论0 收藏0
  • Day 19: EmberJS 入门指南

    摘要:在文件夹内创建,内容如下创建,内容如下使用安装依赖在的头部加入调用命令,同时在你的默认浏览器中打开。最后,我们更新下,给每个报道添加链接修改完毕地后,可以在浏览器中直接看到结果。 编者注:我们发现了有趣的系列文章《30天学习30种新技术》,正在翻译,一天一篇更新,年终礼包。下面是第19天的内容。 到目前为止,我们这一系列文章涉及了Bower、AngularJS、GruntJS、P...

    awesome23 评论0 收藏0
  • [Tips on Ember 2] UI 布局与应用状态关系处理

    摘要:如果说传统的前端开发是以页面为中心来入手的话,那么现代的应用开发就是以状态为中心来着手设计和开发的。初步分析路由是怎么管理状态的复杂的话题简单说在中,应用的每一个可能的状态都是通过体现的。 引子 SPA(单页面应用)的核心是什么? 自该类型应用诞生以来我最多思考的问题就是这个。现在前端 SPA 框架满天飞,许多不是框架的也被称作框架,究竟有什么代表性的层(layer)能让一个系统称得上...

    wayneli 评论0 收藏0
  • Ember.js第七章——测试

    摘要:集成测试集成测试是处于单元测试和验收测试之间的测试。集成测试目的是验证客户端与全系统交互,所有单元测试,以及微观层面具体代码的算法逻辑是否都能通过。集成测试用来验证应用程序各个模块相互关系,比如若干个控件之间的行为。 测试简介 测试是Ember。js框架开发环节中很重要的一环。 现在假设你正在利用Ember框架开发一个博客系统,这个系统包含user和post模型,有登录及创建博客的操作...

    iliyaku 评论0 收藏0
  • 引入计算属性、action、动态内容

    摘要:文章来源引入计算属性动态内容美化主页,增加邮件输入框在主页中增加一个的,在这个组件中增加一个输入框和一个按钮。如果是这种方式,输入框的值默认一直都是,并且在控制器中不能使用属性获取值。 文章来源:引入计算属性、action、动态内容 美化主页,增加邮件输入框 在主页中增加一个Bootstrap的jumbotron,在这个jumbotron组件中增加一个input输入框和一个button...

    Betta 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<