Browse Source

滑动验证码

old
wangqing 5 years ago
parent
commit
94aed2f95a
  1. 1
      package.json
  2. 40
      src/api/index.js
  3. 9
      src/store/modules/user.js
  4. 24
      src/utils/sign.js
  5. 2
      src/views/account/ForgetPwd.vue
  6. 27
      src/views/account/login.vue
  7. 4
      src/views/home/index.vue
  8. 7
      src/views/test.vue

1
package.json

@ -19,7 +19,6 @@
"element-ui": "^2.14.0", "element-ui": "^2.14.0",
"file-saver": "^2.0.2", "file-saver": "^2.0.2",
"js-cookie": "^2.2.1", "js-cookie": "^2.2.1",
"js-md5": "^0.7.3",
"nprogress": "^0.2.0", "nprogress": "^0.2.0",
"vue": "^2.6.12", "vue": "^2.6.12",
"vue-clipboard2": "^0.3.1", "vue-clipboard2": "^0.3.1",

40
src/api/index.js

@ -33,45 +33,14 @@ api.interceptors.request.use(
if (store.getters['user/isLogin']) { if (store.getters['user/isLogin']) {
request.headers.token = store.state.user.token request.headers.token = store.state.user.token
} }
if (request.method == 'post') { // 签名验证
if (request.data instanceof FormData) {
if (store.getters['user/isLogin']) {
// 如果是 FormData 类型(上传图片)
request.data.append('token', store.state.user.token)
}
} else {
// 带上 token
if (request.data == undefined) {
request.data = {}
}
// 参数验签
let timestamp = new Date().getTime()
request.data.timestamp = '' + timestamp
let sign = signMd5Utils.getSign(request.url, request.data)
request.data.sign = sign
}
} else if (request.method === 'get') {
// 带上 token
if (request.params == undefined) { if (request.params == undefined) {
request.params = {} request.params = {}
} }
let timestamp = new Date().getTime() let timestamp = new Date().getTime()
// get 请求所有参数转成string类型 用于签名计算
request.params.timestamp = '' + timestamp request.params.timestamp = '' + timestamp
let strParams = JSON.stringify(request.params, function(key, value) { let sign = signMd5Utils.getSign(request.url, request, timestamp)
if (key) {
if (value == undefined || value == null) {
return undefined
}
return '' + value
}
return value
})
console.log(JSON.stringify(request.params) + ':str' + strParams)
let sign = signMd5Utils.getSign(request.url, JSON.parse(strParams))
request.params.sign = sign request.params.sign = sign
}
return request return request
} }
) )
@ -86,16 +55,18 @@ api.interceptors.response.use(
* 请求出错时 msg 会返回错误信息 * 请求出错时 msg 会返回错误信息
* 则代码如下 * 则代码如下
*/ */
let errCodes = [500, 405, 403]
const res = response.data const res = response.data
if (res.code === 200) { if (res.code === 200) {
return Promise.resolve(res) return Promise.resolve(res)
} else if (res.code === 500 || res.code == 403) { } else if (errCodes.includes(res.code)) {
// 这里做错误提示,如果使用了 element ui 则可以使用 Message 进行提示 // 这里做错误提示,如果使用了 element ui 则可以使用 Message 进行提示
Message({ Message({
message: res.msg || 'Error', message: res.msg || 'Error',
type: 'error', type: 'error',
duration: 5 * 1000 duration: 5 * 1000
}) })
return Promise.reject(res)
} else if (res.code === 401) { } else if (res.code === 401) {
// 有一个接口进入该方法 其他接口则不在进入 // 有一个接口进入该方法 其他接口则不在进入
let reLogin = store.getters['global/isReLogin'] let reLogin = store.getters['global/isReLogin']
@ -111,6 +82,7 @@ api.interceptors.response.use(
}) })
}) })
} }
return Promise.reject(res)
} }
return Promise.resolve(res) return Promise.resolve(res)
}, },

9
src/store/modules/user.js

@ -26,10 +26,7 @@ const actions = {
}) })
}, },
logout(context) { logout(context) {
context.commit('setData', { context.commit('delData')
token: null,
userInfo: null
})
} }
} }
@ -39,6 +36,10 @@ const mutations = {
localStorage.setItem('userInfo', JSON.stringify(data.userInfo)) localStorage.setItem('userInfo', JSON.stringify(data.userInfo))
state.token = data.token state.token = data.token
state.userInfo = JSON.stringify(data.userInfo) state.userInfo = JSON.stringify(data.userInfo)
},
delData() {
localStorage.removeItem('token')
localStorage.removeItem('userInfo')
} }
} }

24
src/utils/sign.js

@ -1,7 +1,8 @@
/* eslint-disable no-alert */ /* eslint-disable no-alert */
import md5 from 'js-md5' import CryptoJS from 'crypto-js'
import constants from './constants' import constants from './constants'
import _ from 'lodash' import _ from 'lodash'
export default class sign { export default class sign {
/** /**
* json参数升序 * json参数升序
@ -23,17 +24,34 @@ export default class sign {
return sortObj return sortObj
} }
/** /**
* @param url 请求的url,应该包含请求参数(url的?后面的参数) * @param url 请求的url,应该包含请求参数(url的?后面的参数)
* @param requestParams 请求参数(POST的JSON参数) * @param requestParams 请求参数(POST的JSON参数)
* @returns {string} 获取签名 * @returns {string} 获取签名
*/ */
static getSign(url, requestParams) { static getSign(url, request, timestamp) {
let requestParams = {}
if (request.params) {
// get 请求所有参数转成string类型 用于签名计算
requestParams = JSON.parse(JSON.stringify(request.params, function(key, value) {
if (key) {
if (value == undefined || value == null) {
return undefined
}
return '' + value
}
return value
}))
}
let dataParams = request.data ? request.data : {}
let urlParams = this.parseQueryString(url) let urlParams = this.parseQueryString(url)
let jsonObj = _.merge(urlParams, requestParams) let jsonObj = _.merge(urlParams, requestParams)
jsonObj = _.merge(jsonObj, dataParams)
let requestBody = this.sortAsc(jsonObj) let requestBody = this.sortAsc(jsonObj)
console.log(constants.signSecret + JSON.stringify(requestBody)) console.log(constants.signSecret + JSON.stringify(requestBody))
return md5(constants.signSecret + JSON.stringify(requestBody)).toLowerCase() console.log(CryptoJS.MD5(constants.signSecret + JSON.stringify(requestBody)).toString().toLowerCase())
return CryptoJS.MD5(constants.signSecret + JSON.stringify(requestBody)).toString().toLowerCase()
} }
/** /**

2
src/views/account/ForgetPwd.vue

@ -26,7 +26,7 @@
</el-form-item> </el-form-item>
</el-form> </el-form>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="邮箱注册" name="email"> <el-tab-pane label="邮箱找回" name="email">
<el-form ref="emailRegForm" status-icon :rules="emailRetrieveRules" :model="retrieveAccountForm" <el-form ref="emailRegForm" status-icon :rules="emailRetrieveRules" :model="retrieveAccountForm"
label-width="0px" label-width="0px"
> >

27
src/views/account/login.vue

@ -188,14 +188,26 @@
</el-tabs> </el-tabs>
</el-col> </el-col>
</el-row> </el-row>
<Verify
ref="verify"
:mode="'pop'"
:captcha-type="'blockPuzzle'"
:img-size="{ width: '330px', height: '155px' }"
@success="verifySuccessHandle"
/>
</div> </div>
</template> </template>
<script> <script>
import {getCurrentDomain} from '@/utils' import {getCurrentDomain} from '@/utils'
//
import Verify from '@/components/verifition/Verify'
export default { export default {
name: 'Login', name: 'Login',
components: {
Verify
},
data() { data() {
const validatePassword = (rule, value, callback) => { const validatePassword = (rule, value, callback) => {
// /^(?=.*\d)(?=.*[a-zA-Z])(?=.*[\W_]).{10,20}$/ // /^(?=.*\d)(?=.*[a-zA-Z])(?=.*[\W_]).{10,20}$/
@ -269,6 +281,17 @@ export default {
}, },
registerHandleClick() { registerHandleClick() {
}, },
verifySuccessHandle(params) {
let slideCode = params.captchaVerification
this.$api.request({
url: '/login/account',
method: 'post',
params: {slideCode},
data: this.accountForm
}).then(res => {
this.loginSuccessHandle(res.data)
})
},
// //
getLoginWxQrCode() { getLoginWxQrCode() {
this.wxQrCodeLoading = true this.wxQrCodeLoading = true
@ -357,9 +380,7 @@ export default {
loginHandle() { loginHandle() {
this.$refs['accountLoginForm'].validate(valid => { this.$refs['accountLoginForm'].validate(valid => {
if (valid) { if (valid) {
this.$api.post('/login/account', this.accountForm).then(res => { this.$refs.verify.show()
this.loginSuccessHandle(res.data)
})
} else { } else {
return false return false
} }

4
src/views/home/index.vue

@ -38,7 +38,7 @@
> >
<div class="user-person-menu"> <div class="user-person-menu">
<div> <div>
<p class="nick-name">{{ getUserInfo.name }}</p> <p v-if="getUserInfo" class="nick-name">{{ getUserInfo.name }}</p>
</div> </div>
<div class="person-menu-divider" /> <div class="person-menu-divider" />
<div> <div>
@ -62,7 +62,7 @@
</div> </div>
</div> </div>
<div slot="reference" style="display: flex; align-items: center; justify-content: center;"> <div slot="reference" style="display: flex; align-items: center; justify-content: center;">
<img :src="getUserInfo.avatar" class="user-avatar"> <img v-if="getUserInfo" :src="getUserInfo.avatar" class="user-avatar">
</div> </div>
</el-popover> </el-popover>
</el-col> </el-col>

7
src/views/test.vue

@ -5,7 +5,7 @@
:mode="'pop'" :mode="'pop'"
:captcha-type="'blockPuzzle'" :captcha-type="'blockPuzzle'"
:img-size="{ width: '330px', height: '155px' }" :img-size="{ width: '330px', height: '155px' }"
@success="'success'" @success="success"
/> />
<button @click="useVerify">调用验证组件</button> <button @click="useVerify">调用验证组件</button>
</div> </div>
@ -14,14 +14,17 @@
<script> <script>
// //
import Verify from '@/components/verifition/Verify' import Verify from '@/components/verifition/Verify'
export default { export default {
name: 'App', name: 'App',
components: { components: {
Verify Verify
}, },
created() {
},
methods: { methods: {
success(params) { success(params) {
// eslint-disable-next-line no-debugger
debugger
// params , 便 // params , 便
console.log(params) console.log(params)
}, },

Loading…
Cancel
Save