当前位置: 首页 > article >正文

基于uniapp的登录状态保持(APP免登录)

基于uniapp的登录状态保持(APP免登录)

           本文介绍了uniapp的登录状态保持(APP免登录)实现方法。在rouyi-uniapp框架开发中,解决用户退出软件/关闭应用/更新安装包后,再打开进入应用需要重新登录,不符合用户使用习惯。本文介绍了如何通过将用户登录信息存储到缓存和文件中,判断用户登录状态直接进入应用。用户登录信息用必要存储到文件中,解决安装更新包更新后用户私有应用缓存被删除。

一、主要思路

  1. 改造登录方法,登录成功后,留存登录状态和登录信息、token等到缓存和本地txt文件中。(安装更新包更新后用户私有应用缓存被删除, 存储到文件中可解决问题)
  2. App.vue为公共组件,每次打开应用或者任意页面都会执行方法。在该文件中写入读取缓存和本地txt文件的方法,如果留存用户登录信息,则自动执行登录方法并跳转到首页。如果缓存和文件里都没有用户登录信息,则跳转到登录页。

二、Uniapp主要技术应用

1、uniapp本地缓存(非持久化)

const userInfo = uni.getStorageSync('userInfo'); //同步获取本地数据

uni.setStorage({   key: 'userInfo',   data: user,});//设置本地存储数据

2、Uniapp文件缓存(持久化)

//文件缓存插件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

// 数据持久化存储
// 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

import filePersistentIO from './filePersistentIO'

Vue.prototype.$filePersistentIO = filePersistentIO

三、实现案例

1、登录方法

登录信息持久化存储和缓存

(1)pages/login.vue

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()
  }
 })
},

 

  // 登录成功后,处理函数
  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')
    })
}
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,将登录信息存储到缓存。退出登录时清除登录信息。

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根组件读取登录缓存和文件

onLaunch: function() {
// 加入如下代码
 const userInfo = uni.getStorageSync('userInfo'); //同步获取本地数据
 
 //判断本地缓存是否存在数据
 if (userInfo != "") {
  //传到vuex里面储存起来,并改变登录状态
  this.login(userInfo)

// 成功即跳转到首页
  this.$tab.reLaunch('/pages/index')
 }
},

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')
       }
     }
},
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)*/

  })
},


http://www.kler.cn/news/293150.html

相关文章:

  • 基于yolov8的西红柿检测系统python源码+onnx模型+评估指标曲线+精美GUI界面
  • 【QT】十分钟全面理解 信号与槽的机制
  • Java并发编程实战 04 | 使用WaitNotify时要注意什么?
  • 黑马点评6——优惠券秒杀—Redis消息队列实现异步秒杀
  • 智联云采 SRM2.0 autologin 身份认证绕过漏洞复现
  • Spring、SpringMVC、SpringBoot都是什么,有什么区别
  • 如何使用事件流相关操作
  • Maven聚合与继承
  • 11、Django Admin启用对计算字段的过滤
  • 大数据-111 Flink 安装部署 YARN部署模式 FlinkYARN模式申请资源、提交任务
  • Java反射机制讲解
  • C++set与map容器
  • 10Python的Pandas:样式Style
  • 数据访问:JPA
  • Django ORM - 如何单独使用 Django 数据库
  • AutosarMCAL开发——基于EB Gpt驱动
  • 【王树森】BERT:预训练Transformer模型(个人向笔记)
  • 2024 年高教社杯全国大学生数学建模竞赛题目-C 题 农作物的种植策略
  • 【Cesium实体创建】
  • HTML:charset讲解
  • Elasticsearch 再次开源
  • 开源云原生数据库PolarDB PostgreSQL 15兼容版本正式发布
  • 计算机视觉中,什么是上下文信息(contextual information)?
  • uuid uuid uuid
  • SpringBoot总结
  • 理解 Axios、jQuery Ajax 和 Fetch 的差别
  • C/C++内存详解
  • Qt/QML学习-Tumbler
  • 电商创新:基于亚马逊国际商品详情API返回值的策略
  • 数学基础 -- 线性代数之LU分解