Node平台上的OAUTH2.0认证服务器搭建 (2)

1)refresh token
为了用户登录授权、获取授权码、提交授权码及Client Secret,Cient ID等这个复杂的过程,而在第一次获得accessToken的时候附带的refreshToken。
/**
 * Save token.
 */
InMemoryCache.prototype.saveToken = function(token, client, user) {
  this.tokens.push({
    accessToken: token.accessToken,
    accessTokenExpiresAt: token.accessTokenExpiresAt,
    clientId: client.clientId,
    refreshToken: token.refreshToken,
    refreshTokenExpiresAt: token.refreshTokenExpiresAt,
    userId: user.id
  });
  return { accessToken: 'foobar',  refreshToken: 'foobiz', client: {}, user: {} };
};


2)Postman测试
-----authorize-----
POST /oauth2/authorize?state=foobiz HTTP/1.1
Host: localhost:3000
Content-Type: application/x-www-form-urlencoded
Cache-Control: no-cache
Postman-Token: 9307f9f1-2b91-ed61-cd72-137a6baa78e3


client_id=thom&response_type=code&user_id=u_thom


-----token-----
POST /oauth2/token HTTP/1.1
Host: localhost:3000
Cache-Control: no-cache
Postman-Token: 0cdb283a-903e-3907-eb80-eee630985487
Content-Type: application/x-www-form-urlencoded


client_id=thom&client_secret=nightworld&grant_type=password&username=thomseddon&password=nightworld


-----post call /api/v1/users-----
POST /api/v1/users HTTP/1.1
Host: localhost:3000
Authorization: Bearer foobar
Cache-Control: no-cache
Postman-Token: 3de36e9f-2cc7-dd46-6b82-65b5c49965da
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW


-----get call /api/v1/users-----
GET /api/v1/users HTTP/1.1
Host: localhost:3000
Authorization: Bearer foobar
Cache-Control: no-cache

Postman-Token: df113160-8595-252f-ff0e-a614c3b8172b



3)Axios测试
因为跨域问题,在axios中访问:localhost:3000/api/vi/users,并不能像postman那样获得正确的结果。
我们采用的是Vue,下面是login.vue(vue-cli自动生成的框架)的部份修改代码。
-----login.vue-----
<script>
import { setCookie, getCookie } from '../assets/js/cookie.js'
export default {
  data () {
    return {
      showLogin: true,
      showRegister: false,
      showTishi: false,
      tishi: '',
      username: '',
      password: '',
      newUsername: '',
      newPassword: '',
      devs: []
    }
  },
  mounted () {
    /* 页面挂载获取cookie,如果存在username的cookie,则跳转到主页,不需登录 */
    if (getCookie('username')) {
      this.$router.push('/home')
    }
  },
  methods: {
    login () {
      if (this.username === '' || this.password === '') {
        alert('请输入用户名或密码')
      } else {
        let data = { username: this.username, password: this.password }
        this.$http
          .get('http://localhost:3000/api/v1/users', data)

          .then(res => {
            console.log(res)
            /* 接口的传值是(-1,该用户不存在),(0,密码错误),同时还会检测管理员账号的值 */
            if (res.data === -1) {
              this.tishi = '该用户不存在'
              this.showTishi = true
            } else if (res.data === 0) {
              this.tishi = '密码输入错误'
              this.showTishi = true
            } else if (res.data === 'admin') {
              /* 路由跳转this.$router.push */
              this.$router.push('/main')
            } else {
              this.tishi = '登录成功'
              this.showTishi = true
              setCookie('username', this.username, 1000 * 60)
              setTimeout(
                function () {
                  this.$router.push('/home')
                }.bind(this),
                1000
              )
            }
          })
      }
    }
  }
}
</script>


下面是main.js修改之后的。主要是添加了Authorization的Bearer Token。
-----main.js-----
import Vue from 'vue'
import AppA from './App'
import router from './router'
import axios from 'axios'


axios.interceptors.request.use(function (config) {
  const token = 'foobar' // this.$store.state.token
  if (token) {
    config.headers.Authorization = `Bearer ${token}`
    console.log(config)
  }
  return config
}, function (err) {
  return Promise.reject(err)
})
Vue.prototype.$http = axios
Vue.config.productionTip = false
// console.log('test')
/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  components: { AppA },
  template: '<AppA/>'
})
console.log(AppA.name)


为了跨域,express后端的代码主要处理了跨域的时候,浏览器发出的options命令,这个命令不要oauth2进行鉴权。
参考如下的修改的app.js。
-----app.js-----
var path = require('path');


var logger = require('morgan');
var cookieParser = require('cookie-parser');
var createError = require('http-errors');
var oauthserver = require('express-oauth-server');
var express = require('express');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');


var app = express();
var mo = require('./model/model.js');
var memorymodel = new mo();


app.oauth = new oauthserver({
  model: memorymodel,
  grants:['password', 'authorization_code', 'refresh_token']
});


// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');


app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(indexRouter);
app.options('*', function(req, res, next){
  res.setHeader('Access-Control-Allow-Origin', '*');
  res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
  res.setHeader('Access-Control-Allow-Headers', 'Authorization,X-Requested-With,content-type');
  res.setHeader('Access-Control-Allow-Credentials', true);
  next();
});

/* authorize provide authorize code to clientside */
app.use('/oauth2/authorize', app.oauth.authorize(
  {
    authenticateHandler: {
      handle: (req, res) => {
        return req.body.user_id === 'u_thom';
      }
    }
  })
);
/* get access token */
app.use('/oauth2/token', app.oauth.token());
/* authenticate protect the resource api (client side should provide token) */
app.get('/api/v1/*', app.oauth.authenticate());
app.post('/api/v1/*', app.oauth.authenticate());


app.use('/api/v1/users', usersRouter);
//app.use('/api/v1/sshports', sshportsRouter);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  next(createError(404));
});


// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};


  // render the error page
  res.status(err.status || 500);
  res.render('error');
});


module.exports = app;

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值