yapi-plugin-cas插件修改

2,150 阅读2分钟

问题:发现此插件对我们使用的sso服务器不匹配,无法登录成功YApi,结合yapi-plugin-qsso插件对yapi-plugin-cas做了代码修改。

经验:根据不同公司sso或cas服务器及验证方式或参数名不同,插件使用方式(或代码)可能需要做不同调整。改完登录截图如下:

具体修改说明如下。

一、此处使用的sso登录地址类似如下,前面是要使用sso服务器网址,ref后面是yapi的登录地址: https://login.sso.test.com/login?ref=http://yapi.yourdomain.com:3000

另外,登录后yapi需要从sso服务器获取用户信息的网址类似如下,sid是登录成功后sso返回的固定参数,但每次参数值不一样,一次有效,过期也失效: https://login.sso.test.com/login?ref=http://yapi.yourdomain.com:3000&sid=123dgrcvshjgrhtdvjdfhjgjko

访问sso登录地址,获取用户信息后的结果举例,当前主要使用了user: {"mail": "lixiaoming@163.com", "memberOf": "CN=yourgg,OU=MailGroups,DC=test,DC=163,DC=com", "user": "lixiaoming", "display": "李晓明"}

二、yapi的config.json修改类似如下:

   "plugins": [
      {
         "name": "cas",
         "options": {
            "type": "cas",
            "LOGIN_SERVER": "https://login.sso.test.com/login?ref=",
            "emailPostfix": "@your.cn",
            "AUTH_SERVER": "https://login.sso.test.com/login?ref="
         }
      }
   ]

三、yapi-plugin-cas/client.js代码修改完如下:

import React, { Component } from 'react'

const qualifyURL = (url, encode) => {
  url = url || '';
  let ret = location.protocol + '//' + location.host + (url.substr(0, 1) === '/' ? '' : location.pathname.match(/.*\//)) + url;
  if (encode) {
    ret = encodeURIComponent(ret);
  }
  return ret;
}

module.exports = function (options) {

  const handleLogin = () => {
    const loginURI = '/api/user/login_by_token';
    const { LOGIN_SERVER } = options;
    let ret = qualifyURL(loginURI, true);
    let redirectURL = LOGIN_SERVER  + ret;
    location.href = redirectURL;
  }

  const WSComponent = () => (
    <button onClick={handleLogin} className="btn-home btn-home-normal" >SSO 域账号登录</button>
  )
  this.bindHook('third_login', WSComponent);
}

四、server.js代码修改完如下:

const request = require('request');
const parseString = require('xml2js').parseString;

module.exports = function (options) {
  const { AUTH_SERVER, emailPostfix } = options
  this.bindHook('third_login', (ctx) => {
    let ticket = ctx.request.body.sid || ctx.request.query.sid;
    let requestUrl = ctx.request.protocol + '://' + ctx.request.host + ctx.request.path;
    let validateUrl = AUTH_SERVER +  encodeURIComponent(requestUrl) + '&sid=' + ticket;
    return new Promise((resolve, reject) => {
//	console.log('cas url:',validateUrl);
      request.get(validateUrl, function(error, response, body) {
        if (!error && response.statusCode == 200) {
         let result = JSON.parse(body);
          if (result && result.user ) {
            let ret = {
              email: result.user + emailPostfix,
              username: result.user
            };
            resolve(ret);
//	console.log('cas ret :',ret);
          } else {
            reject(result);
//	console.log('cas res er:',result);
          }
 } else {
          reject(error);
//        console.log('cas get er:',error);
        }
      })
    })
  });
}

五、注意事项 虽然修改js代码有些是即时生效的,但是这个插件里会有一些静态资源,而我直接使用的“生产环境”启动方式,所以改完代码后需要按如下执行重新编译(ykit也是开源命令,如果没有需自行安装)。

  cd vendors

编译:

  ykit pack -m

重新启动服务:

  node server/app.js

六、相关主要参考资料链接

源码
https://github.com/wsfe/yapi-plugin-cas
https://github.com/YMFE/yapi-plugin-qsso
React教程
https://www.runoob.com/react/react-tutorial.html
YApi官档
https://hellosean1025.github.io/yapi/devops/index.html

七、最后再推荐一个代码搜索命令ack,linux下可以直接yum安装:yum install ack 使用举例,以关键字“koa”搜索.js文件(--js),忽略大小写(-i),忽略static目录: ack --js "koa" -i --ignore-dir=static