提交 830bddfa 编写于 作者: 芊里

Merge branch 'master' of https://gitee.com/dcloud/base-app

......@@ -187,6 +187,27 @@
"navigationBarBackgroundColor": "#FFFFFF",
"backgroundColor": "#F8F8F8"
},
"condition": {
"list": [{
"path": "uni_modules/uni-login-page/pages/index/index",
"style": {
"navigationBarTitleText": "",
"app-plus": {
"animationType": "none",
"popGesture": "none",
"titleNView": {
"buttons": [{
"text": "帮助",
"type": "none",
"fontSize": "16px",
"width": "60px"
}]
}
}
}
}],
"current": 0
},
"tabBar": {
"color": "#7A7E83",
"selectedColor": "#007AFF",
......
......@@ -20,6 +20,7 @@
} from 'vuex';
const db = uniCloud.database();
const userTable = db.collection('uni-id-users')
export default {
data() {
return {
......@@ -60,9 +61,7 @@
* value 更新后的用户字段值
*/
uploadUserInfo(data){
db.collection('uni-id-users').where({
_id: this.userInfo._id
})
userTable.doc(this.userInfo._id)
.update(data)
.then(res=>{
console.log(res);
......
......@@ -14,14 +14,14 @@
</uni-grid-item>
</uni-grid>
<uni-list class="center-list" v-for="(sublist , index) in ucenterList">
<uni-list-item v-for="item in sublist"
:title="item.title"
link :rightText="item.rightText"
:clickable="true"
:to="item.to"
@click="ucenterListClick(item)"
></uni-list-item>
</uni-list>
<uni-list-item v-for="item in sublist"
:title="item.title"
link :rightText="item.rightText"
:clickable="true"
:to="item.to"
@click="ucenterListClick(item)"
></uni-list-item>
</uni-list>
</view>
</template>
......@@ -58,10 +58,10 @@
],
ucenterList: [
[{
title: '阅读过的文章',
title: '阅读过的文章',
to: ''
}, {
title: '我的积分',
title: '我的积分',
to: ''
}],
[{
......@@ -125,12 +125,12 @@
url: './edit/edit'
})
}
},
tapGrid(index){
uni.showToast({
title: '你点击了,第'+index+'',
icon: 'none'
});
},
tapGrid(index){
uni.showToast({
title: '你点击了,第'+index+'',
icon: 'none'
});
}
}
}
......@@ -167,7 +167,7 @@
.userInfo {
width: 750rpx;
padding: 20rpx;
padding: 20rpx;
padding-top:50px;
background-color: #2F85FC;
flex-direction: column;
......@@ -181,7 +181,7 @@
.logo-img {
width: 150rpx;
height: 150rpx;
border-radius: 150rpx;
border-radius: 150rpx;
border: solid 1px #FFFFFF;
}
......@@ -216,20 +216,20 @@
font-family: texticons;
}
.center-list {
.center-list {
margin-bottom: 30rpx;
background-color: #f9f9f9;
}
.center-list-cell {
width: 750rpx;
width: 750rpx;
background-color: #007AFF;
height: 40rpx;
}
.grid{
background-color: #FFFFFF;
margin:25rpx 0;
.grid{
background-color: #FFFFFF;
margin:25rpx 0;
}
.uni-grid .text {
font-size: 26rpx;
......@@ -239,17 +239,17 @@
.uni-grid .item /deep/ .uni-grid-item__box {
justify-content: center;
align-items: center;
}
/*修改边线粗细示例*/
/* #ifndef APP-NVUE */
.center-list /deep/ .uni-list--border:after,
.center-list /deep/ .uni-list--border-top ,
.center-list /deep/ .uni-list--border-bottom{
-webkit-transform: scaleY(0.2);
transform: scaleY(0.2);
}
/* #endif */
}
/*修改边线粗细示例*/
/* #ifndef APP-NVUE */
.center-list /deep/ .uni-list--border:after,
.center-list /deep/ .uni-list--border-top ,
.center-list /deep/ .uni-list--border-bottom{
-webkit-transform: scaleY(0.2);
transform: scaleY(0.2);
}
/* #endif */
</style>
</style>
{
"name": "user-center",
"version": "1.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"uni-captcha": {
"version": "file:../../../uni_modules/uni-captcha/uniCloud/cloudfunctions/common/uni-captcha"
},
"uni-id": {
"version": "file:../../../uni_modules/uni-id/uniCloud/cloudfunctions/common/uni-id"
}
}
}
{
"name": "user-center",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"uni-captcha": "file:../../../uni_modules/uni-captcha/uniCloud/cloudfunctions/common/uni-captcha",
"uni-id": "file:../../../uni_modules/uni-id/uniCloud/cloudfunctions/common/uni-id"
}
}
......@@ -3,7 +3,7 @@
"permission": {
"read": true,
"create": false,
"update": "doc.uid == auth.uid",
"update": "doc._id == auth.uid",
"delete": false
},
"properties": {
......
......@@ -44,13 +44,9 @@
"smsSecret": "d6c424b702d73baa3b6e1a1452469213"
},
"univerify":{
// "appid": "__UNI__GameCat",
// "apiKey":"c5f80ebad34aaf0ae22958d866287521",
// "apiSecret":"f921890ca9c248273eadaf9b4137cf5c"
"appid": "__UNI__BC54A00",
"apiKey":"d1e36bcd497b3795434d900dcfdd44dc",
"apiSecret":"2feb378ff1114362b20ac179b572293e"
"appid": "__UNI__GameCat",
"apiKey":"c5f80ebad34aaf0ae22958d866287521",
"apiSecret":"f921890ca9c248273eadaf9b4137cf5c"
}
}
}
<template>
<view class="quick-login-box">
<view class="item" v-for="({text,logo,name},index) in providerList" :key="index" @click="login(name)">
<image class="logo" :src="logo" mode="widthFix"></image>
<text class="login-title">{{text}}</text>
<view class="item" v-for="({id},index) in oauthServices" :key="index" @click="login(id)" v-if="config[id].isChecked">
<image class="logo" :src="config[id].logo" mode="widthFix"></image>
<text class="login-title">{{config[id].text}}</text>
</view>
</view>
</template>
......@@ -14,37 +14,61 @@
config: {
"weixin": {
"text": "微信登陆",
"logo": "../../static/login/img/weixin.png"
"logo": "../../static/login/img/weixin.png",
"isChecked":true
},
"apple": {
"text": "苹果登陆",
"logo": "../../static/login/img/apple.png",
"isChecked":true
},
"univerify": {
"text": "一键登陆",
"logo": "../../static/login/img/univerify.png",
"isChecked":true
},
"qq": {
"text": "QQ登陆",
"logo": "../../static/login/img/qq.png"
"logo": "../../static/login/img/qq.png",
"isChecked":false //暂未提供该登陆方式的接口示例
},
"xiaomi": {
"text": "小米登陆",
"logo": "../../static/login/img/qq.png"
},
"apple": {
"text": "苹果登陆",
"logo": "../../static/login/img/apple.png"
"logo": "../../static/login/img/qq.png",
"isChecked":false //暂未提供该登陆方式的接口示例
},
"sinaweibo": {
"text": "微博登录",
"logo": "../../static/login/img/sinaweibo.png"
"logo": "../../static/login/img/sinaweibo.png",
"isChecked":false //暂未提供该登陆方式的接口示例
},
"univerify": {
"text": "一键登陆",
"logo": "../../static/login/img/univerify.png"
}
},
providerList: [],
providerList: [],
oauthServices:[],
univerifyStyle: {
"fullScreen": true, // 是否全屏显示,true表示全屏模式,false表示非全屏模式,默认值为false。
"backgroundColor": "#ffffff", // 授权页面背景颜色,默认值:#ffffff
}
}
},
mounted() {
mounted() {
//获取当前环境能用的快捷登陆方式
// #ifdef APP-PLUS
plus.oauth.getServices(oauthServices=>{
this.oauthServices = oauthServices
console.log(oauthServices);
},err=>{
uni.showModal({
title: '获取服务供应商失败:' +JSON.stringify(err),
showCancel: false,
confirmText: '知道了'
});
console.error('获取服务供应商失败:' + JSON.stringify(err));
})
// #endif
/*
uni.getProvider({
"service": "oauth",
success: res => {
......@@ -57,11 +81,20 @@
console.error('获取服务供应商失败:' + JSON.stringify(err));
}
})
*/
},
methods: {
login(type) {
// #ifndef H5
let oauthService = this.oauthServices.find((service) => service.id == type)
// #ifdef APP-PLUS
uni.showLoading({mask: true});
if(type=='weixin'){
oauthService.authorize(({code})=>{
console.log(code);
this.quickLogin({code},type)
})
}
uni.login({
"provider": type,
"univerifyStyle":this.univerifyStyle,
......@@ -77,21 +110,24 @@
uni.hideLoading()
console.log(err);
if(err.errCode===30002){
console.log('你手动关闭了,一键登陆');
console.log('在一键登陆界面,点击其他登陆方式');
}
if(err.errCode===30003){
uni.navigateBack()
}
}
})
// #endif
},
quickLogin(authResult,type){
quickLogin(params,type){
//请勿直接使用authResult中的unionid或openid直接用于登陆,前端的数据都是不可靠的
console.log({...authResult,type});
console.log({params,type});
uniCloud.callFunction({//联网验证登陆
"name": "user",
"name": "user-center",
"data": {
"action": "quickLogin",
"params": {...authResult,type}
"action": "login_by_"+type,
params
},
success: (e) => {
console.log(e.result);
......
......@@ -3,37 +3,17 @@ const uniID = require('uni-id')
const uniCaptcha = require('uni-captcha')
const db = uniCloud.database()
const dbCmd = db.command
exports.main = async (event, context) => {
let params = event.params || {}
// 登录记录
const loginLog = async (res = {}, type = 'login') => {
const now = Date.now()
const uniIdLogCollection = db.collection('uni-id-log')
let logData = {
deviceId: params.deviceId || context.DEVICEID,
ip: params.ip || context.CLIENTIP,
type,
ua: context.CLIENTUA,
create_date: now
};
Object.assign(logData,
res.code === 0 ? {
user_id: res.uid,
state: 1
} : {
state: 0
})
return uniIdLogCollection.add(logData)
}
const getNeedCaptcha = async () => {
const now = Date.now()
// 查询是否在 {2小时} 内 {前2条} 有 {登录失败} 数据,来确定是否需要验证码
const recordSize = 2;
const recordDate = 120 * 60 * 1000;
exports.main = async (event, context) => {
//event为客户端上传的参数
console.log('event : ' + event)
let params = event.params || {}
//防止黑客恶意破解登陆,连续登陆失败一定次数后,需要用户提供验证码
const getNeedCaptcha = async () => {
//当用户最近“2小时内(recordDate)”登陆失败达到2次(recordSize)时。要求用户提交验证码
const now = Date.now(),
recordDate = 120 * 60 * 1000,
recordSize = 2;
const uniIdLogCollection = db.collection('uni-id-log')
let recentRecord = await uniIdLogCollection.where({
deviceId: params.deviceId || context.DEVICEID,
......@@ -43,38 +23,57 @@ exports.main = async (event, context) => {
.orderBy('create_date', 'desc')
.limit(recordSize)
.get();
return recentRecord.data.filter(item => item.state === 0).length === recordSize;
}
//event为客户端上传的参数
console.log('event : ' + event)
let payload = {}
//设置某些模块不需要token(也就是登陆成功后)才能操作,如果需要token就获取当前操作账户的uid
let noCheckAction = [
'register', 'loginByWeixin', 'checkToken',
'login', 'logout', 'sendSmsCode',
'loginBySms', 'inviteLogin', 'loginByUniverify',
'loginByApple', 'createCaptcha', 'verifyCaptcha',
'refreshCaptcha'
]
if (noCheckAction.indexOf(event.action) === -1) {
'register', 'checkToken','login', 'logout', 'sendSmsCode',
'createCaptcha', 'verifyCaptcha','refreshCaptcha', 'inviteLogin',
'login_by_weixin','login_by_univerify','login_by_apple','loginBySms'
]
console.log(event.action);
if (!noCheckAction.includes(event.action)) {
if (!event.uniIdToken) {
return {
code: 403,
msg: '缺少token'
}
}
payload = await uniID.checkToken(event.uniIdToken)
}
let payload = await uniID.checkToken(event.uniIdToken)
if (payload.code && payload.code > 0) {
return payload
}
params.uid = payload.uid
}
//记录成功登陆的日志
const loginLog = async (res = {}, type = 'login') => {
const now = Date.now()
const uniIdLogCollection = db.collection('uni-id-log')
let logData = {
deviceId: params.deviceId || context.DEVICEID,
ip: params.ip || context.CLIENTIP,
type,
ua: context.CLIENTUA,
create_date: now
};
Object.assign(logData,
res.code === 0 ? {
user_id: res.uid,
state: 1
} : {
state: 0
})
return uniIdLogCollection.add(logData)
}
let res = {}
switch (event.action) {
case 'register':
res = await uniID.register(params);
......@@ -95,10 +94,17 @@ exports.main = async (event, context) => {
}
res.needCaptcha = needCaptcha;
break;
case 'loginByWeixin':
res = await uniID.loginByWeixin(params);
loginLog(res)
break;
case 'login_by_weixin':
res = await uniID.loginByWeixin(params);
loginLog(res)
break;
case 'login_by_univerify':
res = await uniID.loginByUniverify(params)
break;
case 'login_by_apple':
res = await uniID.loginByApple(params)
loginLog(res)
break;
case 'checkToken':
res = await uniID.checkToken(event.uniIdToken);
......@@ -175,13 +181,6 @@ exports.main = async (event, context) => {
case 'getInvitedUser':
res = await uniID.getInvitedUser(params)
break;
case 'loginByUniverify':
res = await uniID.loginByUniverify(params)
break;
case 'loginByApple':
res = await uniID.loginByApple(params)
loginLog(res)
break;
case 'updatePwd':
res = await uniID.updatePwd({
uid: params.uid,
......
'use strict';
const uniID = require('uni-id')
const uniCaptcha = require('uni-captcha')
const db = uniCloud.database()
const dbCmd = db.command
let params,context,res;
class User {
async quickLogin(){
let {access_token,openid,type} = params
switch (type){
case 'weixin':
let userinfo_res = await uniCloud.httpclient.request('https://api.weixin.qq.com/sns/userinfo',
{
method: 'GET',
dataType:"json",
data:{ access_token,openid}
});
return userinfo_res.data//根据access_token,openid得到userinfo
//检查是否已经注册...待续...
break;
case 'univerify':
return uniID.loginByUniverify({access_token,openid})
break;
case 'apple':
return await uniID.loginByApple(params)
break;
default:
return {"code":100,"msg":"暂不提供"+type+"登陆的云端接口演示"}
break;
}
}
async sendSmsCode(){
// 简单限制一下客户端调用频率
const ipLimit = await db.collection('uni-verify').where({
ip: context.CLIENTIP,
created_at: dbCmd.gt(Date.now() - 60000)
}).get()
if (ipLimit.data.length > 0) {
return {
code: 429,
msg: '请求过于频繁'
}
}
const templateId = '11753' // 替换为自己申请的模板id
if (!templateId) {
return {
code: 500,
msg: 'sendSmsCode需要传入自己的templateId,参考https://uniapp.dcloud.net.cn/uniCloud/uni-id?id=sendsmscode'
}
}
const randomStr = '00000' + Math.floor(Math.random() * 1000000)
const code = randomStr.substring(randomStr.length - 6)
return await uniID.sendSmsCode({
mobile: params.mobile,
code,
type: params.type,
templateId
})
}
}
const userClass = new User();
exports.main = async (event, ctx) => {
[{params},context] = [event,ctx]
//1.判断需要token的action是否有token
/*let noCheckAction = ['register', 'loginByWeixin', 'checkToken','login', 'logout', 'sendSmsCode','loginBySms', 'inviteLogin', 'loginByUniverify','loginByApple', 'createCaptcha', 'verifyCaptcha','refreshCaptcha']
if(!noCheckAction.includes(event.action)) {
if (!event.uniIdToken) {
return {"code":403,"msg":"缺少token"}
}
let payload = {}
payload = await uniID.checkToken(event.uniIdToken)
if (payload.code && payload.code > 0) {
return payload
}
params.uid = payload.uid
}*/
try{
return await userClass[event.action]()||res;
}catch(err){
return {"code":404,"msg":err}
}
}
\ No newline at end of file
// 本文件中的json内容将在云函数【运行】时作为参数传给云函数。
// 配置教程参考:https://uniapp.dcloud.net.cn/uniCloud/quickstart?id=runparam
{
"action": "sendSmsCode",
"params": {
"mobile":"17769516081",
"type":"register"
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册