基于uniapp的登录状态保持(APP免登录)
本文介绍了uniapp的登录状态保持(APP免登录)实现方法。在rouyi-uniapp框架开发中,解决用户退出软件/关闭应用/更新安装包后,再打开进入应用需要重新登录,不符合用户使用习惯。本文介绍了如何通过将用户登录信息存储到缓存和文件中,判断用户登录状态直接进入应用。用户登录信息用必要存储到文件中,解决安装更新包更新后用户私有应用缓存被删除。
一、主要思路
- 改造登录方法,登录成功后,留存登录状态和登录信息、token等到缓存和本地txt文件中。(安装更新包更新后用户私有应用缓存被删除, 存储到文件中可解决问题)
- App.vue为公共组件,每次打开应用或者任意页面都会执行方法。在该文件中写入读取缓存和本地txt文件的方法,如果留存用户登录信息,则自动执行登录方法并跳转到首页。如果缓存和文件里都没有用户登录信息,则跳转到登录页。
二、Uniapp主要技术应用
1、uniapp本地缓存(非持久化)
javascript
const userInfo = uni.getStorageSync('userInfo'); //同步获取本地数据
uni.setStorage({ key: 'userInfo', data: user,});//设置本地存储数据
2、Uniapp文件缓存(持久化)
javascript
//文件缓存插件filePersistentIO读取文件
this.$filePersistentIO.read('JTG_USR_TOKEN_INFO.txt').then(res => {
loginInfoFromFile = res
return loginInfoFromFile
/* console.log('loginInfoFromFile res ======================>')
console.log(JSON.stringify(res))
console.log(loginInfoFromFile)*/
})
//文件缓存插件filePersistentIO写入文件
this.$filePersistentIO.storage('JTG_USR_INFO.txt', loginInfo)
3、文件缓存插件
plugins/filePersistentIO.js
javascript
// 数据持久化存储
// let addr = "file://storage/emulated/0/京唐港app/";
// let addr = "file:///storage/emulated/0/";
let addr = "JTGUser/Info/"; // 手机存储的文件位置
export default {
storage(className, data) {
plus.io.requestFileSystem(
// plus.io.PRIVATE_DOC, // 程序私有文档目录常量
// plus.io.PUBLIC_DOWNLOADS, // 程序私有文档目录常量
plus.io.PUBLIC_DOCUMENTS,
fs => {
// 创建或打开文件, fs.root是根目录操作对象,直接fs表示当前操作对象
fs.root.getFile(
addr + className,
{create: true},// 文件不存在则创建
fileEntry => {
// 文件在手机中的路径
fileEntry.createWriter(writer => {
// 写入文件成功完成的回调函数
writer.onwrite = e => {
//console.log('写入成功');
};
// 向文件中写入数据
writer.write(
JSON.stringify(data)
);
// 写入完成回调
writer.onwriteend = function(res) {
console.log('写入文件成功', res.target.fileName);
};
// 写入错误回调
writer.onerror = function(err) {
console.error('写入文件失败', err);
};
});
},
e => {
console.log('getFile failed: ', e);
}
);
},
e => {
console.log(e.message);
}
);
},
read(className) {
let that = this;
return new Promise((resolve, reject) => {
plus.io.requestFileSystem(
// plus.io.PRIVATE_DOC,
// plus.io.PUBLIC_DOWNLOADS,
plus.io.PUBLIC_DOCUMENTS,
fs => {
fs.root.getFile(
addr + className,
{create: false},
fileEntry => {
fileEntry.file(function(file) {
console.log('文件大小:' + file.size + '-- 文件名:' + file.name);
//创建读取文件对象
let fileReader = new plus.io.FileReader();
//以文本格式读取文件数据内容
fileReader.readAsText(file, 'utf-8');
//文件读取操作完成时的回调函数
fileReader.onloadend = (evt) => {
console.log(evt.target.result)
console.log('evt.target.result')
console.log(JSON.parse(evt.target.result),
'JSON.parse(evt.target.result)')
resolve(JSON.parse(evt.target.result))
// sURL = JSON.parse(evt.target.result).URL;
}
// fileReader.onloadend = function(evt) {
// resolve(evt.target.result)
// };
});
},
e => {
reject(e);
}
);
},
e => {
reject(e);
console.log(e.message);
}
);
})
}
}
3、插件引入
plugins/index.js
javascript
import filePersistentIO from './filePersistentIO'
Vue.prototype.$filePersistentIO = filePersistentIO
三、实现案例
1、登录方法
登录信息持久化存储和缓存
(1)pages/login.vue
javascript
import {mapMutations}from 'vuex';
...mapMutations(['login']),
// 密码登录
async pwdLogin() {
this.$store.dispatch('Login', this.loginForm).then(() => {
this.$modal.closeLoading()
//将登陆成功后的账号/密码放入到缓存
let loginInfo = {
username: this.loginForm.username,
password: this.loginForm.password
}
uni.setStorage({
key: 'loginInfo',
data: loginInfo,
});
/** 登录信息持久化存储 */
// 登录成功后将用户名密码存储到文件【安装包更新后-用户名密码自动填充,但不免登录】
this.$filePersistentIO.storage('JTG_USR_INFO.txt',loginInfo)
this.loginSuccess()
}).catch(() => {
if (this.captchaEnabled) {
this.getCode()
}
})
},
javascript
// 登录成功后,处理函数
loginSuccess(result) {
// 设置用户信息
this.$store.dispatch('GetInfo').then(res => {
let userInfo = {
userId: res.user.userName,
token: uni.getStorageSync("token"),
phone: res.user.phonenumber,
userName: res.user.userName,
jurisdiction: res.user.roleS,
}
console.log("state"+uni.getStorageSync("state"))
console.log("userinfo"+userInfo)
debugger
this.login(userInfo)
this.$tab.reLaunch('/pages/index')
})
}
javascript
getLoginInfoFromFile(){
/** 持久化存储数据读取 */
let loginInfoFromFile = null
this.$filePersistentIO.read('JTG_USR_INFO.txt').then(res => {
loginInfoFromFile = res
if (this.loginForm.username != '' && (loginInfoFromFile != "" && loginInfoFromFile.username == '' && loginInfoFromFile.password == '')) {
this.loginForm.username = loginInfoFromFile.username
this.loginForm.password = loginInfoFromFile.password
}
/* console.log('loginInfoFromFile res ======================>')
console.log(JSON.stringify(res))
console.log(loginInfoFromFile)*/
})
},
(2)store/index.js
Mutation触发此处的login,将登录信息存储到缓存。退出登录时清除登录信息。
javascript
import Vue from 'vue'
import Vuex from 'vuex'
import user from '@/store/modules/user'
import businessGlobeVariable from '@/store/modules/businessGlobeVariable'
import getters from './getters'
Vue.use(Vuex)
const store = new Vuex.Store({
modules: {
user,
businessGlobeVariable
},
state: {
hasLogin:false, //用户是否登录
userInfo:{} //用户数据
},
mutations: {
// 登录
login(state,user){
//登录状态为已登录
state.hasLogin = true
state.userInfo = user
//储存用户数据到本地
uni.setStorage({
key: 'userInfo',
data: user,
});
console.log('登陆成功')
console.log(state.hasLogin,state.userInfo)
},
// 退出登录
logout(state,user){
//登录状态为未登录
state.hasLogin = false
state.userInfo = {}
//删除本地储存
uni.removeSavedFile({
key: 'userInfo',
})
console.log('退出登录')
console.log(state.hasLogin,state.userInfo)
}
},
actions: {
},
getters
})
export default store
2、App.vue根组件读取登录缓存和文件
javascript
onLaunch: function() {
// 加入如下代码
const userInfo = uni.getStorageSync('userInfo'); //同步获取本地数据
//判断本地缓存是否存在数据
if (userInfo != "") {
//传到vuex里面储存起来,并改变登录状态
this.login(userInfo)
// 成功即跳转到首页
this.$tab.reLaunch('/pages/index')
}
},
javascript
checkLogin() {
//debugger
console.log('getToken()=>'+getToken())
if (!getToken()) {
this.$tab.reLaunch('/pages/login')
}else{
const userInfo = uni.getStorageSync('userInfo'); //同步获取本地数据
const userInfo1 = this.getLoginTokenInfoFromFile(); //同步获取本地数据(更新安装包后,缓存删除,从文件读取)
//判断本地缓存是否存在数据
if (userInfo != "") {
//传到vuex里面储存起来,并改变登录状态
this.login(userInfo)
this.$tab.reLaunch('/pages/index')
}else if (userInfo1 != "") {
//传到vuex里面储存起来,并改变登录状态
this.login(userInfo1)
this.$tab.reLaunch('/pages/index')
}
}
},
javascript
getLoginTokenInfoFromFile(){
/** 持久化存储数据读取 (用户名及token自动登录)*/
let loginInfoFromFile = null
this.$filePersistentIO.read('JTG_USR_TOKEN_INFO.txt').then(res => {
loginInfoFromFile = res
return loginInfoFromFile
/* console.log('loginInfoFromFile res ======================>')
console.log(JSON.stringify(res))
console.log(loginInfoFromFile)*/
})
},