提交 5732cbba 编写于 作者: DCloud_JSON's avatar DCloud_JSON

1. 新增一键登录授权界面的其他快捷登陆按钮 2. 优化uni-quick-login组件代码 3....

1. 新增一键登录授权界面的其他快捷登陆按钮 2. 优化uni-quick-login组件代码  3. 调整隐私政策协议框勾选逻辑:在登陆页面已勾选,同步勾选。如果没勾选需要手动勾选(为符合应用市场上架要求) 4. 调整登陆页隐私政策协议框位置。  5. 增强路由拦截,新增判断token是否过期。
上级 b5918cc3
......@@ -56,7 +56,7 @@
// #endif
},
onShow: function() {
console.log('App Show')
console.log('App Show')
},
onHide: function() {
console.log('App Hide')
......
## 1.0.22(2021-06-22)
1. 新增一键登录授权界面的其他快捷登陆按钮
2. 优化uni-quick-login组件代码
3. 调整隐私政策协议框勾选逻辑:在登陆页面已勾选,同步勾选。如果没勾选需要手动勾选(为符合应用市场上架要求)
4. 调整登陆页隐私政策协议框位置。
5. 增强路由拦截,新增判断token是否过期。
## 1.0.21(2021-06-21)
优化:uni_modules模式使用uni-id-cf,方便uni-starter与uniCloud-admin的uni-id-cf同步更新。
## 1.0.20(2021-06-18)
......
......@@ -8,7 +8,7 @@ import interceptorChooseImage from '@/uni_modules/json-interceptor-chooseImage/j
// #endif
const db = uniCloud.database()
export default function() {
// #ifndef H5
setTimeout(()=>{
// #endif
......@@ -33,6 +33,7 @@ export default function() {
code, // 错误码详见https://uniapp.dcloud.net.cn/uniCloud/clientdb?id=returnvalue
message
}) {
console.log('onDBError');
// 处理错误
console.log(code,message);
if([
......@@ -199,8 +200,6 @@ export default function() {
tokenExpired
})
}
console.log(e.result.code);
switch (e.result.code){
case 403:
uni.navigateTo({
......@@ -212,6 +211,11 @@ export default function() {
url: "/pages/ucenter/login-page/index/index"
})
break;
case 30203:
uni.navigateTo({
url: "/pages/ucenter/login-page/index/index"
})
break;
case 50101:
uni.showToast({
title: e.result.msg,
......@@ -235,11 +239,13 @@ export default function() {
// console.log(e);
//获取用户的token
const token = uni.getStorageSync('uni_id_token')
//token是否已失效
const tokenExpired = (uni.getStorageSync('uni_id_token_expired') - Date.now()) < 0
//获取当前页面路径(即url去掉"?"和"?"后的参数)
const url = e.url.split('?')[0]
//控制登录优先级
let pages = getCurrentPages();
if (
if ( //判断当前窗口是否为登陆页面,如果是则不重定向路由
url == '/pages/ucenter/login-page/index/index'
&&
pages[pages.length - 1].route.split('/')[2]!='login-page'
......@@ -253,7 +259,7 @@ export default function() {
}
}else{
//拦截强制登录页面
if (needLogin.includes(url) && token == '') {
if (needLogin.includes(url) && (token == ''||tokenExpired)) {
uni.showToast({
title: '请先登录',
icon: 'none'
......
......@@ -18,6 +18,9 @@
computed: {
loginConfig() {
return getApp().globalData.config.router.login
},
agreements() {
return getApp().globalData.config.about.agreements || []
}
},
data() {
......@@ -35,126 +38,110 @@
"path": "/pages/ucenter/login-page/index/index"
}
],
oauthServices: []
oauthServices: [],
config: {
"weixin": {
"text": "微信登录",
"logo": "/static/uni-quick-login/wechat.png",
},
"apple": {
"text": "苹果登录",
"logo": "/static/uni-quick-login/apple.png",
},
"univerify": {
"text": "一键登录",
"logo": "/static/uni-quick-login/univerify.png",
},
"qq": {
"text": "QQ登录",//暂未提供该登录方式的接口示例
"logo": "/static/uni-quick-login/univerify.png",
},
"xiaomi": {
"text": "小米登录",//暂未提供该登录方式的接口示例
"logo": "/static/uni-quick-login/univerify.png",
},
"sinaweibo": {
"text": "微博登录",//暂未提供该登录方式的接口示例
"logo": "/static/uni-quick-login/univerify.png",
}
},
univerifyStyle:{ //一键登录弹出窗的样式配置参数
"fullScreen": true, // 是否全屏显示,true表示全屏模式,false表示非全屏模式,默认值为false。
"backgroundColor": "#ffffff", // 授权页面背景颜色,默认值:#ffffff
"buttons": { // 自定义登陆按钮
"iconWidth": "45px", // 图标宽度(高度等比例缩放) 默认值:45px
"list": []
},
"privacyTerms": {
"defaultCheckBoxState": false, // 条款勾选框初始状态 默认值: true
"textColor": "#BBBBBB", // 文字颜色 默认值:#BBBBBB
"termsColor": "#5496E3", // 协议文字颜色 默认值: #5496E3
"prefix": "我已阅读并同意", // 条款前的文案 默认值:“我已阅读并同意”
"suffix": "并使用本机号码登录", // 条款后的文案 默认值:“并使用本机号码登录”
"privacyItems": []
}
}
}
},
},
watch: {
agree(agree) {
this.univerifyStyle.privacyTerms.defaultCheckBoxState = agree
}
},
props: {
agree: {
type: Boolean,
default () {
return false
}
},
config: {
type: Object,
default () {
return {
"weixin": {
"text": "微信登录",
"logo": "/static/uni-quick-login/wechat.png",
"isChecked": true
},
"apple": {
"text": "苹果登录",
"logo": "/static/uni-quick-login/apple.png",
"isChecked": true
},
"univerify": {
"text": "一键登录",
"logo": "/static/uni-quick-login/univerify.png",
"isChecked": true
},
"qq": {
"text": "QQ登录",
"logo": "/static/uni-quick-login/univerify.png",
"isChecked": false //暂未提供该登录方式的接口示例
},
"xiaomi": {
"text": "小米登录",
"logo": "/static/uni-quick-login/univerify.png",
"isChecked": false //暂未提供该登录方式的接口示例
},
"sinaweibo": {
"text": "微博登录",
"logo": "/static/uni-quick-login/univerify.png",
"isChecked": false //暂未提供该登录方式的接口示例
}
}
}
},
univerifyStyle: {
type: Object,
default () {
return { //一键登录弹出窗的样式配置参数
"fullScreen": true, // 是否全屏显示,true表示全屏模式,false表示非全屏模式,默认值为false。
"backgroundColor": "#ffffff", // 授权页面背景颜色,默认值:#ffffff
}
}
},
},
created() {
// console.log('loginConfig', this.loginConfig);
// console.log('this.getRoute(1)', this.getRoute(1));
let servicesList = this.servicesList
//去掉当前页面对应的登录选项
for (var i = 0; i < servicesList.length; i++) {
if (servicesList[i].path == this.getRoute(1)) {
servicesList.splice(i, 1)
}
}
//去掉配置项中不存在的项
for (var i = 0; i < servicesList.length; i++) {
if (!this.loginConfig.includes(servicesList[i].id)) {
console.log('去掉配置项中不存在的项', servicesList[i].id);
servicesList.splice(i, 1)
}
}
// console.log('servicesList', servicesList);
},
mounted() {
//获取当前环境能用的快捷登录方式
// #ifdef APP-PLUS
plus.oauth.getServices(oauthServices => {
this.oauthServices = oauthServices
oauthServices.forEach(({
id
}) => {
if (this.config[id].isChecked && this.loginConfig.includes(id)) {
if (id == 'weixin') {
if (!plus.runtime.isApplicationExist({
pname: 'com.tencent.mm',
action: 'weixin://'
})) {
console.log("微信应用未安装");
return
}
}
this.servicesList.push({
...this.config[id],
id
})
}
})
// console.log('oauthServices',oauthServices);
}, err => {
uni.hideLoading()
uni.showModal({
title: '获取服务供应商失败:' + JSON.stringify(err),
showCancel: false,
confirmText: '知道了'
});
console.error('获取服务供应商失败:' + JSON.stringify(err));
})
// #endif
// #ifdef MP-WEIXIN
let id = 'weixin'
if (this.loginConfig.includes(id)) {
this.servicesList.push({
...this.config[id],
id
})
}
async created() {
this.univerifyStyle.privacyTerms.privacyItems = this.agreements
let servicesList = this.servicesList
//获取当前环境能用的快捷登录方式
// #ifdef MP-WEIXIN
let id = 'weixin'
if (this.loginConfig.includes(id)) {
servicesList.push({
...this.config[id],
id
})
}
// #endif
// #ifdef APP-PLUS
this.oauthServices = await new Promise((callBack)=>{
plus.oauth.getServices(oauthServices => {
callBack(oauthServices.filter(({nativeClient,id})=>nativeClient&&this.loginConfig.includes(id)))
//只返回1.应用支持 && 2.手机已安装对应客户端 && 3.uni-starter.config.js配置项中存在的快捷登录方式
}, err => {
callBack([])
uni.hideLoading()
uni.showModal({
title: '获取服务供应商失败:' + JSON.stringify(err),
showCancel: false,
confirmText: '知道了'
});
console.error('获取服务供应商失败:' + JSON.stringify(err));
})
})
// #endif
//添加已配置且可用的第三方快捷登陆项
servicesList = servicesList.concat(this.oauthServices.map( ({id})=>{
return {...this.config[id],id}
}))
//设置一键登录功能底下的快捷登陆按钮
servicesList.forEach(({id,logo})=>{
if(id != 'univerify'){
this.univerifyStyle.buttons.list.push({"iconPath":logo,"provider":id})
}
})
//去掉当前页面对应的登录选项
this.servicesList = servicesList.filter(item=>{
return item.path != this.getRoute(1)
})
console.log('servicesList',servicesList,this.servicesList);
},
methods: {
...mapMutations({
......@@ -179,7 +166,7 @@
}
},
login_before(type, navigateBack = true) {
if (!this.agree) {
if (!this.agree&&type!='univerify') {
return uni.showToast({
title: '你未同意隐私政策协议',
icon: 'none'
......@@ -218,7 +205,7 @@
"provider": type,
"univerifyStyle": this.univerifyStyle,
complete: (e) => {
console.log(9527, e);
console.log(e);
},
success: async e => {
console.log(e);
......@@ -249,6 +236,12 @@
icon: 'none'
});
}
if (err.errMsg) {
uni.showToast({
title: "一键登录:" + err.errMsg,
icon: 'none'
});
}
switch (err.errCode) {
case 30002:
console.log('在一键登录界面,点击其他登录方式');
......@@ -272,17 +265,14 @@
title: '点击了第三方登陆',
icon: 'none'
});
switch (err.index) {
case 0:
this.login_before('weixin', false)
break;
case 1:
this.login_before('apple', false)
break;
default:
break;
console.log('点击了第三方登陆,provider:',err.provider);
let {path} = this.servicesList.find(item=>item.id==err.provider)||{}
console.log('path',path);
if(path&&path!=this.getRoute(1)){ //存在路径,且并不是当前已经打开的路径
this.to(path)
}else{
this.login_before(err.provider)
}
break;
default:
console.log(9527, err);
......@@ -297,12 +287,13 @@
console.log({
params,
type
});
let action = 'loginBy'+ type.trim().toLowerCase().replace(type[0], type[0].toUpperCase())
});
let action = 'loginBy' + type.trim().toLowerCase().replace(type[0], type[0].toUpperCase())
uniCloud.callFunction({
name: 'uni-id-cf',
data: {
action,params
action,
params
},
success: ({
result
......@@ -316,12 +307,17 @@
loginSuccess(result)
delete result.userInfo.token
this.setUserInfo(result.userInfo)
} else {
uni.showModal({
content: result.msg,
showCancel: false
});
}
},
complete: () => {
uni.hideLoading()
}
})
})
},
async getUserInfo(e) {
return new Promise((resolve, reject) => {
......
......@@ -85,13 +85,20 @@
},
success: ({result}) => {
console.log(result);
uni.showToast({
title: "短信验证码发送成功",
icon: 'none'
});
this.reverseNumber = Number(this.count);
this.getCode();
this.$emit('getCode');
if(result.code===0){
uni.showToast({
title: "短信验证码发送成功",
icon: 'none'
});
this.reverseNumber = Number(this.count);
this.getCode();
this.$emit('getCode');
}else{
uni.showModal({
content: result.msg,
showCancel: false
});
}
}
})
},
......
......@@ -6,7 +6,6 @@ import openApp from './common/openApp.js';
Vue.config.productionTip = false
openApp();
App.mpType = 'app'
const app = new Vue({
...App,
store
......
{
"id": "uni-starter",
"displayName": "uni-starter",
"version": "1.0.21",
"version": "1.0.22",
"description": "云端一体应用快速开发基本项目模版",
"keywords": [
"uni-starter",
......
......@@ -5,7 +5,7 @@
}
.input-box{
padding:0 15px;
margin-top: 15px;
margin-bottom: 10px;
background-color: #F8F8F8;
border-radius: 6px;
font-size: 28rpx;
......@@ -17,8 +17,8 @@
color: #FFFFFF;
}
.input-box,.get-code{
height: 50px;
line-height: 50px;
height: 45px;
line-height: 45px;
}
.title{
text-align: center;
......
......@@ -4,11 +4,6 @@ export default function(result){
icon: 'none'
});
console.log('登录成功',result);
uni.setStorageSync('uni_id_uid', result.uid)
uni.setStorageSync('uni_id_token', result.token)
uni.setStorageSync('uni_id_token_expired', result.tokenExpired)
//delete result.userInfo.token
// this.setUserInfo(result.userInfo)
var delta = 0//判断需要返回几层
let pages = getCurrentPages();
......
......@@ -2,15 +2,15 @@
<view class="content">
<!-- 顶部文字 -->
<text class="title">登录后即可展示自己</text>
<uni-agreements @setAgree="agree = $event"></uni-agreements>
<!-- 登录框 -->
<input type="number" class="input-box" :inputBorder="false" v-model="phone" maxlength="11"
placeholder="请输入手机号" />
<button class="get-code" :class="{isPhone}" :disabled="!isPhone" :type="isPhone?'primary':'default'"
placeholder="请输入手机号" />
<uni-agreements @setAgree="agree = $event"></uni-agreements>
<button class="get-code" :disabled="!isPhone" :type="isPhone?'primary':'default'"
@click="sendShortMsg">获取短信验证码</button>
<text class="tip">未注册的手机号验证通过后将自动注册</text>
<!-- 登录按钮弹窗 -->
<uni-quick-login :univerifyStyle="univerifyStyle" :agree="agree" ref="uniQuickLogin"></uni-quick-login>
<uni-quick-login :agree="agree" ref="uniQuickLogin"></uni-quick-login>
</view>
</template>
......@@ -20,59 +20,19 @@
data() {
return {
phone: "",
agree: false,
univerifyStyle: {
"fullScreen": true, // 是否全屏显示,true表示全屏模式,false表示非全屏模式,默认值为false。
"backgroundColor": "#ffffff", // 授权页面背景颜色,默认值:#ffffff
"buttons": { // 自定义登陆按钮
"iconWidth": "45px", // 图标宽度(高度等比例缩放) 默认值:45px
"list": []
},
"privacyTerms": {
"defaultCheckBoxState": "true", // 条款勾选框初始状态 默认值: true
"textColor": "#BBBBBB", // 文字颜色 默认值:#BBBBBB
"termsColor": "#5496E3", // 协议文字颜色 默认值: #5496E3
"prefix": "我已阅读并同意", // 条款前的文案 默认值:“我已阅读并同意”
"suffix": "并使用本机号码登录", // 条款后的文案 默认值:“并使用本机号码登录”
"privacyItems": []
}
}
agree: false
}
},
computed: {
isPhone() {
return /^1\d{10}$/.test(this.phone);
},
agreements() {
return getApp().globalData.config.about.agreements || []
}
},
onLoad(e) {
uni.getProvider({
service: 'oauth',
success: res => {
if (~res.provider.indexOf('weixin')&&plus.runtime.isApplicationExist({
pname: 'com.tencent.mm',
action: 'weixin://'
})) {
this.univerifyStyle.buttons.list.push({
"iconPath": "/static/uni-quick-login/wechat.png"
})
}
if (~res.provider.indexOf('apple')) {
this.univerifyStyle.buttons.list.push({
"iconPath": "/static/uni-quick-login/apple.png"
})
}
}
});
//是否优先启动一键登录。即:页面一加载就启动一键登录
univerify_first = e.univerify_first
//#ifdef APP-PLUS
if (univerify_first) {
this.univerifyStyle.privacyTerms.privacyItems = this.agreements
const pages = getCurrentPages();
currentWebview = pages[pages.length - 1].$getAppWebview();
currentWebview.setStyle({
......@@ -85,7 +45,6 @@
//#ifdef APP-PLUS
if (univerify_first) {
// console.log('开始一键登录');
this.agree = true
setTimeout(() => {
this.$refs.uniQuickLogin.login_before('univerify')
}, 100)
......
......@@ -52,7 +52,14 @@
},
},
success: ({result}) => {
this.loginSuccess(result)
if(result.code === 0){
this.loginSuccess(result)
}else{
uni.showModal({
content: result.msg,
showCancel: false
});
}
}
})
......
......@@ -2,13 +2,13 @@
<view class="content">
<!-- 顶部文字 -->
<text class="title">用户名密码登录</text>
<uni-agreements @setAgree="agree = $event"></uni-agreements>
<input class="input-box" :inputBorder="false" v-model="username" placeholder="请输入手机号/用户名"></input>
<input type="password" class="input-box" :inputBorder="false" v-model="password" placeholder="请输入密码"></input>
<view class="captcha-box" v-if="captchaBase64">
<image class="captcha-img" @click="createCaptcha" :src="captchaBase64" mode="widthFix"></image>
<input type="text" class="input-box captcha" :inputBorder="false" v-model="captcha" placeholder="请输入验证码"></input>
</view>
</view>
<uni-agreements @setAgree="agree = $event"></uni-agreements>
<button class="send-btn" :disabled="!canLogin" :type="canLogin?'primary':'default'"
@click="pwdLogin">登录</button>
<!-- 忘记密码 -->
......@@ -108,6 +108,11 @@
success: ({result}) => {
if (result.code === 0) {
this.captchaBase64 = result.captchaBase64
}else{
uni.showModal({
content: result.msg,
showCancel: false
});
}
}
})
......
......@@ -73,6 +73,11 @@ import mixin from '../common/login-page.mixin.js';
console.log(result);
if(result.code === 0){
this.loginSuccess(result)
}else{
uni.showModal({
content: result.msg,
showCancel: false
});
}
}
})
......
<template>
<view class="center">
<view class="center">
<view class="userInfo" @click="toUserInfo">
<image class="logo-img" :src="userInfo.avatar||avatarUrl"></image>
<view class="logo-title">
......@@ -35,7 +35,6 @@
import uniShare from 'uni_modules/uni-share/js_sdk/uni-share.js';
const db = uniCloud.database();
const dbCollectionName = 'uni-id-scores';
export default {
data() {
return {
......@@ -200,7 +199,8 @@
uni.showLoading({
mask: true
})
db.collection(dbCollectionName).where('user_id == $env.uid').field('score,balance').get().then((res) => {
db.collection("uni-id-scores").where('user_id == $env.uid').field('score,balance').get().then((res) => {
console.log(res);
const data = res.result.data[0];
let msg = '';
msg = data ? ('当前积分为' + data.balance) : '当前无积分';
......
......@@ -83,7 +83,7 @@
uni.closeAuthView()
}else{
uni.showModal({
content: JSON.stringify(result.msg),
content: result.msg,
showCancel: false,
complete() {
uni.closeAuthView()
......
// 上次启动时的用户信息
let userInfoHistory = uni.getStorageSync('userInfo') || {};
let state = {
//是否已经登录
hasLogin: Boolean(Object.keys(userInfoHistory).length),
......@@ -22,8 +21,13 @@ let state = {
state.info = Object.assign({}, _info, info);
//设置为已经登录
state.hasLogin = true;
console.log('state.info',state.info);
//存储最新的用户数据到本地持久化存储
uni.setStorageSync('userInfo', state.info);
uni.setStorageSync('uni_id_uid', state.info._id)
uni.setStorageSync('uni_id_token', state.info.token)
uni.setStorageSync('uni_id_token_expired', state.info.tokenExpired)
},
logout(state) {
state.info = {};
......
......@@ -26,7 +26,7 @@ module.exports = {
"/pages/ucenter/userinfo/uploadCutImageToUnicloud",
"/uni_modules/uni-feedback/pages/uni-feedback/add"
],
"login": ["username","smsCode", "univerify", "weixin", "apple"],
"login": ["univerify","smsCode","username", "weixin", "apple"],
/*
根据数组的第0项,决定登录方式的第一优先级。
未列举到的,或设备环境不支持的选项,将被隐藏。
......
{
"passwordSecret": "passwordSecret-demo",
"tokenSecret": "tokenSecret-demo",
"tokenExpiresIn": 7200,
"tokenExpiresIn": 1,
"tokenExpiresThreshold": 600,
"passwordErrorLimit": 6,
"bindTokenToDevice": false,
......
......@@ -92,7 +92,10 @@ exports.main = async (event, context) => {
})
}
//4.记录成功登录的日志方法
const loginLog = async (res = {}) => {
const loginLog = async (res = {}) => {
if(res.code != 0){
return false
}
const now = Date.now()
const uniIdLogCollection = db.collection('uni-id-log')
let logData = {
......@@ -113,7 +116,8 @@ exports.main = async (event, context) => {
if (res.type == 'register') {
await registerSuccess(res.uid)
} else {
if (Object.keys(deviceInfo).length) {
if (Object.keys(deviceInfo).length) {
console.log(979797,{deviceInfo,user_id: res});
//更新当前用户设备信息
await db.collection('uni-id-device').where({
user_id: res.uid
......@@ -212,9 +216,7 @@ exports.main = async (event, context) => {
...params,
queryField: ['username', 'email', 'mobile']
});
if (res.code === 0) {
await loginLog(res);
}
await loginLog(res);
needCaptcha = await getNeedCaptcha();
}
......
const fs = require('fs');
module.exports = function(){
console.log('开始执行脚本change_after');
let changelog = fs.readFileSync(process.cwd()+'/changelog.md', 'utf-8').split("\n")[1];
let changelog = fs.readFileSync(process.cwd() + '/changelog.md', 'utf-8').split("##")[1].split("\n").slice(1).join(' ');
console.log(changelog);
// 这里是修改完相关敏感配置后执行的脚本,你可以在这里自定义逻辑,
......
{
"passwordSecret": "passwordSecret-demo",
"tokenSecret": "tokenSecret-demo",
"tokenExpiresIn": 7200,
"tokenExpiresIn": 1,
"tokenExpiresThreshold": 600,
"passwordErrorLimit": 6,
"bindTokenToDevice": false,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册