前几天装了一下stf环境 ,mac环境搭建stf
环境搭建还是比较简单的。这个平台登陆的时候是没有限制的,只要输入个名称和邮箱就可以登陆。打算修改一下,改成公司内部账号登陆,下面来撸一撸代码。
这张图片是在网上找的,根据这个区分出来了前端和后端代码。
stf前端使用的是angularjs语言开发的(测试小白,以前没有听过?),后端是nodejs(对于使用Java的我来说,这两个语言有点懵)没办法现学现卖,先去看看基本语法,然后在结合stf源码慢慢啃吧。
打开stf地址是http://192.168.110.18:7100/auth/mock/
在res路径下面找到了前端代码,修改.pug文件可以改变前端页面渲染。
先打开signin.pug把邮箱和name换一下,把name输入框换成password输入框。
.login2(ng-controller='SignInCtrl')
.login-wrapper
a(href='./')
img(width='200', height='85', src='/static/logo/exports/STF-512.png', title='STF')
form(name='signin', novalidate, ng-submit='submit()')
.alert.alert-danger(ng-show='error')
span(ng-show='error.$invalid', translate) Check errors below
span(ng-show='error.$incorrect', translate) Incorrect login details
span(ng-show='error.$server', translate) Server error. Check log output.
.form-group
.input-group
span.input-group-addon
i.fa.fa-envelope
input.form-control(ng-model='email', name='email', required, type='email', placeholder='E-mail',
autocorrect='off', autocapitalize='off', spellcheck='false', autocomplete='section-login email')
.alert.alert-warning(ng-show='signin.email.$dirty && signin.email.$invalid')
span(ng-show='signin.email.$error.email', translate) Please enter a valid email
span(ng-show='signin.email.$error.required', translate) Please enter your email
.form-group
.input-group
span.input-group-addon
i.fa.fa-user
input.form-control(ng-model='pwd', name='pwd', required, type='password', placeholder='Password',
autocorrect='off', autocapitalize='off', spellcheck='false', autocomplete='section-login username')
.alert.alert-warning(ng-show='signin.pwd.$dirty && signin.pwd.$invalid')
span(translate) Please enter your password
input.btn.btn-lg.btn-primary.btn-block(type='submit', value='Log In')
再找到前端控制器signin-controller.js,修改之前的name为pwd
module.exports = function SignInCtrl($scope, $http) {
$scope.error = null
//获取前端页面提交的用户名和email
$scope.submit = function() {
var data = {
pwd: $scope.signin.pwd.$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
}
})
}
}
再找到后端登录接口,打开mock.js
var http = require('http')
var express = require('express')
var validator = require('express-validator')
var cookieSession = require('cookie-session')
var bodyParser = require('body-parser')
var serveStatic = require('serve-static')
var csrf = require('csurf')
var Promise = require('bluebird')
var basicAuth = require('basic-auth')
var logger = require('../../util/logger')
var requtil = require('../../util/requtil')
var jwtutil = require('../../util/jwtutil')
var pathutil = require('../../util/pathutil')
var urlutil = require('../../util/urlutil')
var lifecycle = require('../../util/lifecycle')
module.exports = function(options) {
var log = logger.createLogger('auth-mock')
var app = express()
var server = Promise.promisifyAll(http.createServer(app))
lifecycle.observe(function() {
log.info('Waiting for client connections to end')
return server.closeAsync()
.catch(function() {
// Okay
})
})
// 这里没有用到
// BasicAuth Middleware
var basicAuthMiddleware = function(req, res, next) {
function unauthorized(res) {
res.set('WWW-Authenticate', 'Basic realm=Authorization Required')
return res.send(401)
}
var user = basicAuth(req)
if (!user || !user.name || !user.pass) {
return unauthorized(res)
}
if (user.name === options.mock.basicAuth.username &&
user.pass === options.mock.basicAuth.password) {
return next()
}
else {
return unauthorized(res)
}
}
app.set('view engine', 'pug')
app.set('views', pathutil.resource('auth/mock/views'))
app.set('strict routing', true)
app.set('case sensitive routing', true)
app.use(cookieSession({
name: options.ssid
, keys: [options.secret]
}))
app.use(bodyParser.json())
app.use(csrf())
app.use(validator())
app.use('/static/bower_components',
serveStatic(pathutil.resource('bower_components')))
app.use('/static/auth/mock', serveStatic(pathutil.resource('auth/mock')))
app.use(function(req, res, next) {
res.cookie('XSRF-TOKEN', req.csrfToken())
next()
})
if (options.mock.useBasicAuth) {
app.use(basicAuthMiddleware)
}
// 页面请求为ip+端口,重定向到登陆页面
app.get('/', function(req, res) {
res.redirect('/auth/mock/')
})
// 页面请求为ip+端口/auth/mock/,打开登陆页面
app.get('/auth/mock/', function(req, res) {
res.render('index')
})
// 前端请求登陆接口,验证用户名密码是否正确
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('pwd').notEmpty()
req.checkBody('email').isEmail()
})
.then(function() {
log.info('Authenticated "%s"', req.body.email)
var token = jwtutil.encode({
payload: {
email: req.body.email
, pwd: req.body.pwd
}
, secret: options.secret
, header: {
exp: Date.now() + 24 * 3600
}
})
//下面一直到########结束都是新添加的
var Data = {
account: req.body.email
, password: req.body.pwd
}
var postData = JSON.stringify(Data)
var Options = {
hostname: 'www.baidu.com' //这里是公司oa的登录接口
, port: 80
, path: '/api/login/password'
, method: 'post'
, headers: {
'Content-Type': 'application/json;charset=UTF-8'
}
}
var Request = http.request(Options, function(response) {
var responseString = ''
response.on('data', function(chun) {
responseString += chun
})
response.on('end', function() {
var resultObject = JSON.parse(responseString)
if (resultObject.status === 200) {
res.status(200)
.json({
success: true
, redirect: urlutil.addParams(options.appUrl, {
jwt: token
})
})
}
else {
res.status(400)
.json({
success: false
, error: 'ValidationError'
, validationErrors: resultObject.msg
})
}
})
}) //################
Request.on('error', function(err) {
log.error(err)
})
Request.write(postData)
Request.end()
})
.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
}
})
server.listen(options.port)
log.info('Listening on port %d', options.port)
}
再找到修改数据库的代码auth.js
var jwtutil = require('../../../util/jwtutil')
var urlutil = require('../../../util/urlutil')
var dbapi = require('../../../db/api')
module.exports = function(options) {
return function(req, res, next) {
if (req.query.jwt) {
// Coming from auth client
var data = jwtutil.decode(req.query.jwt, options.secret)
var redir = urlutil.removeParam(req.url, 'jwt')
if (data) {
// Redirect once to get rid of the token
dbapi.saveUserAfterLogin({
pwd: data.pwd //这里是修改过的
, email: data.email
, ip: req.ip
})
.then(function() {
req.session.jwt = data
res.redirect(redir)
})
.catch(next)
}
else {
// Invalid token, forward to auth client
res.redirect(options.authUrl)
}
}
else if (req.session && req.session.jwt) {
dbapi.loadUser(req.session.jwt.email)
.then(function(user) {
if (user) {
// Continue existing session
req.user = user
next()
}
else {
// We no longer have the user in the database
res.redirect(options.authUrl)
}
})
.catch(next)
}
else {
// No session, forward to auth client
res.redirect(options.authUrl)
}
}
}
最后找到执行数据库语句操作的代码api.js
var r = require('rethinkdb')
var util = require('util')
var db = require('./')
var wireutil = require('../wire/util')
var dbapi = Object.create(null)
dbapi.DuplicateSecondaryIndexError = function DuplicateSecondaryIndexError() {
Error.call(this)
this.name = 'DuplicateSecondaryIndexError'
Error.captureStackTrace(this, DuplicateSecondaryIndexError)
}
util.inherits(dbapi.DuplicateSecondaryIndexError, Error)
dbapi.close = function(options) {
return db.close(options)
}
dbapi.saveUserAfterLogin = function(user) {
return db.run(r.table('users').get(user.email).update({
name: user.email.split('@')[0] //这里是修改过的
, ip: user.ip
, lastLoggedInAt: r.now()
}))
.then(function(stats) {
if (stats.skipped) {
return db.run(r.table('users').insert({
email: user.email
, name: user.email.split('@')[0] //这里是修改过的
, ip: user.ip
, group: wireutil.makePrivateChannel()
, lastLoggedInAt: r.now()
, createdAt: r.now()
, forwards: []
, settings: {}
}))
}
return stats
})
}
dbapi.loadUser = function(email) {
return db.run(r.table('users').get(email))
}
dbapi.updateUserSettings = function(email, changes) {
return db.run(r.table('users').get(email).update({
settings: changes
}))
}
dbapi.resetUserSettings = function(email) {
return db.run(r.table('users').get(email).update({
settings: r.literal({})
}))
}
dbapi.insertUserAdbKey = function(email, key) {
return db.run(r.table('users').get(email).update({
adbKeys: r.row('adbKeys').default([]).append({
title: key.title
, fingerprint: key.fingerprint
})
}))
}
dbapi.deleteUserAdbKey = function(email, fingerprint) {
return db.run(r.table('users').get(email).update({
adbKeys: r.row('adbKeys').default([]).filter(function(key) {
return key('fingerprint').ne(fingerprint)
})
}))
}
dbapi.lookupUsersByAdbKey = function(fingerprint) {
return db.run(r.table('users').getAll(fingerprint, {
index: 'adbKeys'
}))
}
dbapi.lookupUserByAdbFingerprint = function(fingerprint) {
return db.run(r.table('users').getAll(fingerprint, {
index: 'adbKeys'
})
.pluck('email', 'name', 'group'))
.then(function(cursor) {
return cursor.toArray()
})
.then(function(groups) {
switch (groups.length) {
case 1:
return groups[0]
case 0:
return null
default:
throw new Error('Found multiple users for same ADB fingerprint')
}
})
}
dbapi.lookupUserByVncAuthResponse = function(response, serial) {
return db.run(r.table('vncauth').getAll([response, serial], {
index: 'responsePerDevice'
})
.eqJoin('userId', r.table('users'))('right')
.pluck('email', 'name', 'group'))
.then(function(cursor) {
return cursor.toArray()
})
.then(function(groups) {
switch (groups.length) {
case 1:
return groups[0]
case 0:
return null
default:
throw new Error('Found multiple users with the same VNC response')
}
})
}
dbapi.loadUserDevices = function(email) {
return db.run(r.table('devices').getAll(email, {
index: 'owner'
}))
}
dbapi.saveDeviceLog = function(serial, entry) {
return db.run(r.table('logs').insert({
serial: serial
, timestamp: r.epochTime(entry.timestamp)
, priority: entry.priority
, tag: entry.tag
, pid: entry.pid
, message: entry.message
}
, {
durability: 'soft'
}))
}
dbapi.saveDeviceInitialState = function(serial, device) {
var data = {
present: false
, presenceChangedAt: r.now()
, provider: device.provider
, owner: null
, status: device.status
, statusChangedAt: r.now()
, ready: false
, reverseForwards: []
, remoteConnect: false
, remoteConnectUrl: null
, usage: null
}
return db.run(r.table('devices').get(serial).update(data))
.then(function(stats) {
if (stats.skipped) {
data.serial = serial
data.createdAt = r.now()
return db.run(r.table('devices').insert(data))
}
return stats
})
}
dbapi.setDeviceConnectUrl = function(serial, url) {
return db.run(r.table('devices').get(serial).update({
remoteConnectUrl: url
, remoteConnect: true
}))
}
dbapi.unsetDeviceConnectUrl = function(serial) {
return db.run(r.table('devices').get(serial).update({
remoteConnectUrl: null
, remoteConnect: false
}))
}
dbapi.saveDeviceStatus = function(serial, status) {
return db.run(r.table('devices').get(serial).update({
status: status
, statusChangedAt: r.now()
}))
}
dbapi.setDeviceOwner = function(serial, owner) {
return db.run(r.table('devices').get(serial).update({
owner: owner
}))
}
dbapi.unsetDeviceOwner = function(serial) {
return db.run(r.table('devices').get(serial).update({
owner: null
}))
}
dbapi.setDevicePresent = function(serial) {
return db.run(r.table('devices').get(serial).update({
present: true
, presenceChangedAt: r.now()
}))
}
dbapi.setDeviceAbsent = function(serial) {
return db.run(r.table('devices').get(serial).update({
present: false
, presenceChangedAt: r.now()
}))
}
dbapi.setDeviceUsage = function(serial, usage) {
return db.run(r.table('devices').get(serial).update({
usage: usage
, usageChangedAt: r.now()
}))
}
dbapi.unsetDeviceUsage = function(serial) {
return db.run(r.table('devices').get(serial).update({
usage: null
, usageChangedAt: r.now()
}))
}
dbapi.setDeviceAirplaneMode = function(serial, enabled) {
return db.run(r.table('devices').get(serial).update({
airplaneMode: enabled
}))
}
dbapi.setDeviceBattery = function(serial, battery) {
return db.run(r.table('devices').get(serial).update({
battery: {
status: battery.status
, health: battery.health
, source: battery.source
, level: battery.level
, scale: battery.scale
, temp: battery.temp
, voltage: battery.voltage
}
}
, {
durability: 'soft'
}))
}
dbapi.setDeviceBrowser = function(serial, browser) {
return db.run(r.table('devices').get(serial).update({
browser: {
selected: browser.selected
, apps: browser.apps
}
}))
}
dbapi.setDeviceConnectivity = function(serial, connectivity) {
return db.run(r.table('devices').get(serial).update({
network: {
connected: connectivity.connected
, type: connectivity.type
, subtype: connectivity.subtype
, failover: !!connectivity.failover
, roaming: !!connectivity.roaming
}
}))
}
dbapi.setDevicePhoneState = function(serial, state) {
return db.run(r.table('devices').get(serial).update({
network: {
state: state.state
, manual: state.manual
, operator: state.operator
}
}))
}
dbapi.setDeviceRotation = function(serial, rotation) {
return db.run(r.table('devices').get(serial).update({
display: {
rotation: rotation
}
}))
}
dbapi.setDeviceNote = function(serial, note) {
return db.run(r.table('devices').get(serial).update({
notes: note
}))
}
dbapi.setDeviceReverseForwards = function(serial, forwards) {
return db.run(r.table('devices').get(serial).update({
reverseForwards: forwards
}))
}
dbapi.setDeviceReady = function(serial, channel) {
return db.run(r.table('devices').get(serial).update({
channel: channel
, ready: true
, owner: null
, reverseForwards: []
}))
}
dbapi.saveDeviceIdentity = function(serial, identity) {
return db.run(r.table('devices').get(serial).update({
platform: identity.platform
, manufacturer: identity.manufacturer
, operator: identity.operator
, model: identity.model
, version: identity.version
, abi: identity.abi
, sdk: identity.sdk
, display: identity.display
, phone: identity.phone
, product: identity.product
, cpuPlatform: identity.cpuPlatform
, openGLESVersion: identity.openGLESVersion
}))
}
dbapi.loadDevices = function() {
return db.run(r.table('devices'))
}
dbapi.loadPresentDevices = function() {
return db.run(r.table('devices').getAll(true, {
index: 'present'
}))
}
dbapi.loadDevice = function(serial) {
return db.run(r.table('devices').get(serial))
}
dbapi.saveUserAccessToken = function(email, token) {
return db.run(r.table('accessTokens').insert({
email: email
, id: token.id
, title: token.title
, jwt: token.jwt
}))
}
dbapi.removeUserAccessToken = function(email, title) {
return db.run(r.table('accessTokens').getAll(email, {
index: 'email'
}).filter({title: title}).delete())
}
dbapi.loadAccessTokens = function(email) {
return db.run(r.table('accessTokens').getAll(email, {
index: 'email'
}))
}
dbapi.loadAccessToken = function(id) {
return db.run(r.table('accessTokens').get(id))
}
module.exports = dbapi
这样就可以使用公司内部的账号密码登录了。
加班写的,思维有点乱,有时间整理一下。
来源:CSDN
作者:hm372788571
链接:https://blog.csdn.net/hm372788571/article/details/84797948