uni-id-pages login-by-google实现
login-by-google uni-cloud团队没实现,现开源login-by-google的实现
/*** Google登录* @param {Object} params* @param {Object} params.googleInfo - Google用户信息* @param {String} params.googleInfo.id - Google用户唯一ID* @param {String} params.googleInfo.name - 用户全名* @param {String} params.googleInfo.email - 用户邮箱* @param {String} params.googleInfo.picture - 用户头像URL* @param {String} params.googleInfo.given_name - 名字* @param {String} params.googleInfo.family_name - 姓氏* @param {Boolean} params.googleInfo.verified_email - 邮箱是否已验证* @returns {Object} 登录成功后的用户信息和token*/
const {userCollection,db,dbCmd,LOG_TYPE
} = require('../../common/constants')
const {ERROR
} = require('../../common/error')module.exports = async function (params = {}) {try {const { uniIdCommon } = thisconsole.log('Login by Google params received:', JSON.stringify(params))// Check if params is properly structuredif (!params || typeof params !== 'object') {console.error('Invalid params format:', params)throw new Error('Invalid params format')}// Ensure googleInfo exists, using multiple strategies to find valid Google infolet googleInfo = null// Strategy 1: Check if googleInfo is a nested propertyif (params.googleInfo && typeof params.googleInfo === 'object') {googleInfo = params.googleInfoconsole.log('Found googleInfo as nested property')} // Strategy 2: Check if params itself contains the Google IDelse if (params.id) {googleInfo = {id: params.id,name: params.name,email: params.email,picture: params.picture,given_name: params.given_name,family_name: params.family_name,verified_email: params.verified_email}console.log('Extracted googleInfo directly from params')}// Strategy 3: Check if any property of params might contain the Google infoelse {// Look for any property that might be the Google info objectfor (const key in params) {const prop = params[key]if (prop && typeof prop === 'object' && prop.id) {googleInfo = propconsole.log(`Found googleInfo in params.${key}`)break}}}// Final validation of Google infoif (!googleInfo || !googleInfo.id) {console.error('Google info validation failed:', JSON.stringify(googleInfo || params))throw new Error('Google info is required - no valid Google user ID found')}console.log('Using Google Info:', JSON.stringify(googleInfo))// 查询是否已存在此Google账号的用户const userRecord = await userCollection.where({'google.id': googleInfo.id}).get()console.log('User lookup result:', JSON.stringify(userRecord))let uidif (userRecord && userRecord.data && userRecord.data.length > 0) {// 已存在用户,更新Google信息uid = userRecord.data[0]._idconsole.log('Existing user found, updating Google info for user:', uid)await userCollection.doc(uid).update({google: {id: googleInfo.id,name: googleInfo.name || '',email: googleInfo.email || '',picture: googleInfo.picture || '',given_name: googleInfo.given_name || '',family_name: googleInfo.family_name || '',verified_email: googleInfo.verified_email || false},last_login_date: Date.now(),last_login_ip: this.getUniversalClientInfo().clientIP})} else {// 不存在用户,创建新用户console.log('No existing user found, creating new user with Google info')try {const insertResult = await userCollection.add({google: {id: googleInfo.id,name: googleInfo.name || '',email: googleInfo.email || '',picture: googleInfo.picture || '',given_name: googleInfo.given_name || '',family_name: googleInfo.family_name || '',verified_email: googleInfo.verified_email || false},nickname: googleInfo.name || 'Google User', // 使用Google名称作为昵称email: googleInfo.email || '', // 设置邮箱avatar: googleInfo.picture || '', // 设置头像register_date: Date.now(),register_ip: this.getUniversalClientInfo().clientIP,last_login_date: Date.now(),last_login_ip: this.getUniversalClientInfo().clientIP})console.log('New user created, insert result:', JSON.stringify(insertResult))uid = insertResult.id} catch (err) {console.error('Error creating new user:', err)throw new Error('Failed to create new user: ' + (err.message || JSON.stringify(err)))}}if (!uid) {throw new Error('Failed to get or create user ID')}// 记录登录日志await this.middleware.uniIdLog({data: {user_id: uid},type: LOG_TYPE.LOGIN})// 生成token - 使用uniIdCommon的createToken方法console.log('Generating token for user:', uid)let tokenInfotry {tokenInfo = await uniIdCommon.createToken({uid})console.log('Token generated:', tokenInfo)} catch (err) {console.error('Error creating token:', err)throw new Error('Failed to create token: ' + (err.message || JSON.stringify(err)))}// 获取用户完整信息let userInfotry {const userResult = await userCollection.doc(uid).get()if (!userResult.data || userResult.data.length === 0) {throw new Error('User data not found')}userInfo = userResult.data[0]// 返回用户信息和tokenconst result = {...tokenInfo,uid,userInfo: {...userInfo,token: tokenInfo.token,tokenExpired: tokenInfo.tokenExpired}}console.log('Login success, returning result')return result} catch (err) {console.error('Error getting user info:', err)throw new Error('Failed to get user info: ' + (err.message || JSON.stringify(err)))}} catch (err) {console.error('Login by Google failed:', err)throw err}
}