背景
项目有一个web系统,需要接入STF.但是直接访问STF网站的首页,会跳转到STF登录页面。现在希望绕过登录操作。我使用的是STF的mock模式
安装说明
我刚开始是在TesterHome上看的如何安装。但是,我是希望修改STF的源码的。我没有看到TesterHome有类似帖子的介绍。我把这个部分说一下。首先安装部分,还是进openSTF的首页,查看标准的安装过程。
然后,在下载phantomjs的时候可能会非常慢,我推荐使用淘宝镜像:
npm install phantomjs --phantomjs_cdnurl=https://npm.taobao.org/dist/phantomjs
将依赖包安装成功之后,下载stf源码,然后执行命令
npm install && npm link
如果你修改了stf源码,关闭当前运行的stf,执行命令gulp clean && gulp webpack:build && stf local,修改会生效
调试方案的话,推荐直接打log日志,代码如下所示
var logger = require('../../../util/logger')
var log = logger.createLogger('guess the client')
log.info('jwt is ')
require() 的路径是-- 包含log打印日志的文件相对于'/yourHomeDir/stf-2.1.0/lib/util/logger.js'的路径
然后,控制台就可以看到了打印的消息
安装小tips
在使用npm时,可以使用淘宝的镜像。淘宝镜像以及使用方法
STF框架
STF是基于node.js,它的中间件使用的是Express框架,前端使用angular框架,如果想要二次开发,这2个框架的基本知识最好熟悉一下。
后端拦截器
写过Web程序的都应该知道,会存在前端拦截器和后端拦截器。首先找到后端的拦截器,再找的前端拦截器。说一下思路。之前看这篇文章,在/res/auth/mock,目录下找到了如下的代码段
$scope.submit = function() {
var data = {
name: $scope.signin.username.$modelValue
, email: $scope.signin.email.$modelValue
}
$scope.invalid = false
$http.post('/auth/api/v1/mock', data)
.success(function(response) {
$scope.error = null
location.replace(response.redirect)
})
.error(function(response) {
switch (response.error) {
case 'ValidationError':
$scope.error = {
$invalid: true
}
break
case 'InvalidCredentialsError':
$scope.error = {
$incorrect: true
}
break
default:
$scope.error = {
$server: true
}
break
}
})
}
这段代码重要是$http.post('/auth/api/v1/mock', data), 我们可以猜到这段代码的意思,是向后端的某个接口,发送用户名和密码。如果我们对项目STF全局搜索关键字"/auth/api/v1/mock", 看到后端对这个接口的处理的代码。果然,发现了文件"/stf-2.1.0/lib/units/auth/mock.js"的代码段
app.post('/auth/api/v1/mock', function(req, res) {
var log = logger.createLogger('auth-mock')
log.setLocalIdentifier(req.ip)
switch (req.accepts(['json'])) {
case 'json':
requtil.validate(req, function() {
req.checkBody('name').notEmpty()
req.checkBody('email').isEmail()
})
.then(function() {
log.info('Authenticated "%s"', req.body.email)
var token = jwtutil.encode({
payload: {
email: req.body.email
, name: req.body.name
}
, secret: options.secret
, header: {
exp: Date.now() + 24 * 3600
}
})
log.info('appurl is "%s", token is "%s"',options.appUrl, token)
log.info('redirect url is "%s"', urlutil.addParams(options.appUrl, {
jwt: token
}))
res.status(200)
.json({
success: true
, redirect: urlutil.addParams(options.appUrl, {
jwt: token
})
})
})
.catch(requtil.ValidationError, function(err) {
res.status(400)
.json({
success: false
, error: 'ValidationError'
, validationErrors: err.errors
})
})
.catch(function(err) {
log.error('Unexpected error', err.stack)
res.status(500)
.json({
success: false
, error: 'ServerError'
})
})
break
default:
res.send(406)
break
}
})
这个代码段重要的点是urlutil.addParams(options.appUrl, {jwt: token}), 将token打印处理,看输出的到底是什么值,发现值如下所示
jwt=eyJhbGciOiJIUzI1NiJ9.eyJlbWFpbCI6InNoZXJhbmp1bkB3ZWlkaWFuLmNvbSIsIm5hbWUiOiJzaGVyYW5qdW4ifQ.w9JJtvHr32q71BRmbu4c0w9ezwD51P8v-bEgiRoW6qU
我们打开STF的首页,跳转到登录页面,在首页增加上面的参数。可以看到,无需登录,我们就进STF的首页。那么从外部系统进入免登进入STF的方案就可以出来了:
在mock.js中增加一个新的接口,get方法,接受参数值username,返回jwt。我们仿造上面函数,代码如下所示:
app.get('/auth/api/fromzeus/mock', function(req, res) {
var log = logger.createLogger('auth-mock')
log.setLocalIdentifier(req.ip)
log.info('Authenticated "%s"', req.query.name)
log.info('Authenticated ip is "%s"', req.ip)
var user = new Buffer(req.query.name, 'base64').toString('ascii')
user = user.trim()
log.info('base64解码的内容 "%s"',user)
if (!user) {
res.status(400)
.json({
success: false
, error: 'ValidationError'
, validationErrors: err.errors
})
}
log.info('secrest is "%s"',options.secret)
//todo:异常处理
var token = jwtutil.encode({
payload: {
email: user + "@126.com"
, name: user
}
, secret: options.secret
// , header: {
// exp: Date.now() + 24 * 3600
// }
})
log.info('appurl is "%s", token is "%s"',options.appUrl, token)
log.info('token is "%s"', token)
res.status(200)
.json({
success: true
, token: token
})
})
如何在关闭浏览器后,立即释放设备
通过捕获浏览器的关闭事件,来决定是否释放设备。这个方案当初调研时因为不可用,所以直接pass掉了。本质上之所以有这个解决方案的原因是: 在关闭浏览器后,能有一个入口,释放设备。那么,方案来了:
1.我们有两个页面,第一个设备列表页,第二个是设备调试页面(也就是stf的嵌入页面)。即使设备调试页面被关闭,它的状态还是调试中,我们可以根据设备列表页,来释放设备。
a.设备列表页
b.设备调试页
参考链接
安装npm
淘宝镜像
express框架
angular框架
express路由