• Ionic3的http请求如何实现token验证,并且超时返回登录页


    要求

      后台提供的接口,不能让人随便输入个链接就能访问,而是要加入一个token,token是动态的,每次访问的时候判断,有权限并且未过期的时候才可以访问接口。

    后台的设计是

      在登录的时候,首先要post提交一个请求,根据用户名密码,返回一个动态token,这个token会在服务器保存一段时间。在前端的其他接口请求的时候,都要在header中添加这个token,后台会进行验证。只有验证成功,才会返回对应的接口内容,否则会抛出401异常。

    请求效果

      首先使用postman查看正常请求的效果
      第一次登录请求时,添加了Header和Body以后,返回一个动态token,其结果如下:

      服务器中保存了这个token值,然后再请求其他的get请求时,需要在Header中拼接这个token,才可以正常返回

    添加token验证

      Ionic的使用的是httpclient 实现的请求,所有的请求被我写到了一个公共的http-api.service.ts 里面去了
      方法如下:

    public access_token: string = '';
    get<T>(endpoint: string, params?: any) {
      const headers = {
        headers: {
          'Authorization': this.access_token
        }
      };
      if (params) {
        if (!options) {
          options = {'params': params};
        } else {
          options['params'] = params;
        }
      }
      return this.http.get<T>(this.url + '/' + endpoint, headers);
    }

      在登录的时候,先进行token验证,并且将返回的验证码信息保存在http-api.service.ts 中

    public firstPost(username: string, password: string) {
      const headers = {
        headers: {
          'Authorization': 'Basic Y2xpZW50OnNlY3JldA==',
          'Content-Type': 'application/x-www-form-urlencoded'
        }
      };
    
      /*先token验证,虽然是post请求,但是发现直接将参数写到params 里面报错,所以就直接写到了url里面去了*/
      this.httpApi.post('oauth/token?grant_type=password&username=' + username + '&password=' + password, null
        , headers).subscribe(val => {
    //返回值里,access_token代表生成的token验证码
          if (val != null && val['access_token'] != null) {
            this.httpApi.access_token = 'Bearer ' + val['access_token'];
          }
        }, response => {
      let toast = this.toastCtrl.create({
           message: '账号或密码错误',
           duration: 2000,
           position: 'bottom'
           });
          toast.present(toast);
        },
        () => {
        });
    }

     备注:这样做的有一个缺点。因为把token值保存在service中,service是单例的,当service刷新的时候,这个token值就不存在了。而在angular中,网上说,刷新页面,就会刷新service。所以每次刷新页面,必须重新登录生成新的token 值,否则就会报401错误。为了解决这个问题,只有想办法把token值 保存在一个能够永远取到的地方了,比如 window.localStorage ,事实上这也是比较好的一个办法。

    window.localStorage.setItem('access_token', 'Bearer ' + val['access_token']);

    实现token超时,返回登录页面功能

    1、添加自定义拦截器custom.error.handler.ts,如果返回401错误,这调用一个监听器方法,返回登录页(注意:a.这里Ionic 和 Angular是不一样的;b.没有@Injectable(),就没法使用构造函数)

    import {ErrorHandler, Injectable} from "@angular/core";
    import {Events} from "ionic-angular";
    
    @Injectable()
    export class MyErrorHandler implements ErrorHandler {
    
      constructor(private events: Events) {
      }
    
      handleError(err: any): void {
        if (err.status === 401) {
          this.events.publish('userCheck');
        }
        // do something with the errorswitch (res.status) {
      }
    }

    2、在app.module.ts 中添加引入

    import {MyErrorHandler} from "./service/custom.error.handler";
    ...
      providers: [
        {provide: ErrorHandler, useClass: MyErrorHandler}
      ]
    ...

    3、在一个Service 中添加一个全局变量,保证token超时只执行一次返回登录页方法

    @Injectable()
    export class CommonService {
      /**
       * 全局变量,保证userCheck 监听器方法,只执行一次
       * @type {boolean} true可以执行, false不可以执行
       */
      public userCheckNum: boolean = true;
    ...

    4、在tabs.ts文件中添加监听器

    ionViewDidLoad() {
      this.userCheckListenEvents();
    }
    
    ionViewWillUnload() {
      this.events.unsubscribe('userCheck');
    }
    
    userCheckListenEvents() {
      this.events.subscribe('userCheck', () => {
        if(this.commonService.userCheckNum){
          this.commonService.userCheckNum = false;
          let loader = this.loadingCtrl.create({
            content: "链接超时,正在返回登录页",
            duration: 3000
          });
          loader.present();
          loader.onDidDismiss(() => {
            this.commonService.userCheckNum = true;
            this.nav.setRoot(LoginPage);
          });
    
        }
      });
    }

    附录

      后台使用的是cuba platform 框架,cuba中关于token的设计是直接集成在登录功能里面的,在web-app.properties 配置文件里面可以进行配置
      如果添加 cuba.rest.anonymousEnabled = true ,那么任何人都可以访问了,就没有token验证
      如果有token验证,可以添加下面的配置,设置过期时间,单位是秒
        cuba.rest.client.tokenExpirationTimeSec=60
      具体参考官网文档:https://doc.cuba-platform.com/manual-6.8/rest_api_v2_ex_get_token.html

     

    原创文章,欢迎转载,转载请注明出处!

  • 相关阅读:
    正向代理和反向代理
    python的reduce,map,zip,filter和sorted函数
    sed和awk的简单使用
    nginx+uWSGI+django+virtualenv+supervisor发布web服务器
    nginx负载均衡
    nginx入门与实战
    python开发之virtualenv与virtualenvwrapper讲解
    Linux下的python3,virtualenv,Mysql、nginx、redis安装配置
    Linux系统基础优化及常用命令
    vim与程序员
  • 原文地址:https://www.cnblogs.com/acm-bingzi/p/ionic3token.html
Copyright © 2020-2023  润新知