【uniapp】uniapp实现单点登录、打包H5部署到线上

引言

uni-app是一个使用Vue.js开发所有前端应用的框架,开发者编写一套代码,可发布到iOS、Android、Web(响应式)、以及各种小程序等多个平台。单点登录(Single Sign-On,简称SSO)是一种身份验证服务,允许用户使用一个登录ID访问多个相互信任的应用系统,而无需在每个系统中都进行登录操作。

本文将详细介绍如何在uniapp中实现单点登录功能,以及如何将uniapp项目打包成H5应用并部署到线上。

单点登录(SSO)原理简介

单点登录的基本原理是通过一个统一的认证中心来管理用户的登录状态。当用户在一个系统中登录后,认证中心会生成一个令牌(token),用户访问其他系统时,只需携带这个令牌即可完成身份验证,无需重新登录。

单点登录的流程通常包括以下步骤:

  1. 用户在应用A上登录,认证中心验证用户身份并生成token
  2. 认证中心将token返回给应用A
  3. 用户访问应用B,应用B重定向到认证中心
  4. 认证中心验证token的有效性
  5. 验证通过后,认证中心允许用户访问应用B

uniapp实现单点登录的步骤

1. 准备工作

首先,我们需要准备以下内容:

  • 一个已搭建好的认证中心(SSO服务器)
  • 一个或多个uniapp应用
  • 了解基本的HTTP请求和token验证机制

2. 登录页面实现

在uniapp中,我们可以创建一个登录页面,用于接收用户名和密码,并向认证中心发送登录请求。

<template>
  <view class="container">
    <view class="login-form">
      <input type="text" v-model="username" placeholder="请输入用户名" />
      <input type="password" v-model="password" placeholder="请输入密码" />
      <button @click="handleLogin">登录</button>
    </view>
  </view>
</template>

<script>
export default {
  data() {
    return {
      username: '',
      password: ''
    }
  },
  methods: {
    handleLogin() {
      // 向认证中心发送登录请求
      uni.request({
        url: 'https://your-sso-server.com/login',
        method: 'POST',
        data: {
          username: this.username,
          password: this.password
        },
        success: (res) => {
          if (res.data.success) {
            // 登录成功,保存token
            uni.setStorageSync('token', res.data.token);
            // 获取重定向URL
            const redirectUrl = uni.getStorageSync('redirectUrl') || '/pages/index/index';
            // 跳转到首页
            uni.redirectTo({
              url: redirectUrl
            });
          } else {
            uni.showToast({
              title: '登录失败:' + res.data.message,
              icon: 'none'
            });
          }
        },
        fail: (err) => {
          uni.showToast({
            title: '登录请求失败',
            icon: 'none'
          });
        }
      });
    }
  }
}
</script>

<style>
.container {
  padding: 20px;
}
.login-form input {
  height: 40px;
  margin-bottom: 10px;
  border: 1px solid #ddd;
  padding: 0 10px;
}
.login-form button {
  background-color: #007aff;
  color: white;
  height: 40px;
  line-height: 40px;
  text-align: center;
  border: none;
}
</style>

3. 路由守卫实现

为了保护需要登录才能访问的页面,我们需要实现路由守卫。在uniapp中,我们可以通过main.js来全局配置路由守卫。

// main.js
import Vue from 'vue'
import App from './App'

Vue.config.productionTip = false

// 全局路由守卫
const whiteList = ['/pages/login/login']; // 白名单,不需要登录就可以访问的页面

function hasPermission(url) {
  // 检查当前URL是否在白名单中
  return whiteList.some(path => url.indexOf(path) !== -1);
}

// 封装请求拦截器
const request = (options) => {
  // 获取token
  const token = uni.getStorageSync('token');
  
  // 如果有token,则添加到请求头
  if (token) {
    options.header = options.header || {};
    options.header['Authorization'] = 'Bearer ' + token;
  }
  
  return new Promise((resolve, reject) => {
    uni.request({
      ...options,
      success: (res) => {
        // 如果返回401(未授权),则清除token并跳转到登录页
        if (res.statusCode === 401) {
          uni.removeStorageSync('token');
          uni.redirectTo({
            url: '/pages/login/login'
          });
          return;
        }
        resolve(res);
      },
      fail: (err) => {
        reject(err);
      }
    });
  });
};

// 挂载到Vue原型上
Vue.prototype.$request = request;

App.mpType = 'app'

const app = new Vue({
  ...App
})
app.$mount()

4. 实现单点登录跳转

当用户访问需要登录的页面时,如果未登录,应该重定向到登录页面,并记录当前页面URL,以便登录成功后跳转回来。

// 在App.vue中
export default {
  onLaunch: function() {
    // 检查是否需要登录
    const pages = getCurrentPages();
    const currentPage = pages[pages.length - 1];
    const url = currentPage.route;
    
    if (!hasPermission(url) && !uni.getStorageSync('token')) {
      // 保存当前页面URL
      uni.setStorageSync('redirectUrl', '/' + url);
      // 跳转到登录页
      uni.redirectTo({
        url: '/pages/login/login'
      });
    }
  }
}

5. 跨域处理

由于单点登录涉及到跨域请求,我们需要在uniapp中处理跨域问题。

在H5环境下,可以通过配置代理来解决跨域问题。在manifest.json文件中添加以下配置:

{
  "name": "应用名称",
  "appid": "__UNI__XXXXXXX",
  "description": "",
  "versionName": "1.0.0",
  "versionCode": "100",
  "transformPx": false,
  "h5": {
    "devServer": {
      "https": false,
      "proxy": {
        "/api": {
          "target": "https://your-sso-server.com",
          "changeOrigin": true,
          "ws": true,
          "pathRewrite": {
            "^/api": ""
          }
        }
      }
    }
  }
}

uniapp打包H5的步骤

1. 配置manifest.json

manifest.json文件中,配置H5相关的设置:

{
  "name": "应用名称",
  "appid": "__UNI__XXXXXXX",
  "description": "",
  "versionName": "1.0.0",
  "versionCode": "100",
  "transformPx": false,
  "h5": {
    "router": {
      "mode": "hash",
      "base": "/"
    },
    "title": "应用标题",
    "optimization": {
      "treeShaking": {
        "enable": true
      }
    }
  }
}

2. 执行打包命令

在项目根目录下,执行以下命令进行H5打包:

# 使用HBuilderX打包
# 或者使用命令行打包
npm run build:h5

执行成功后,会在项目根目录下生成/dist/build/h5文件夹,里面包含了打包后的H5应用文件。

3. 本地预览

在本地预览打包后的H5应用,可以安装一个简单的HTTP服务器,如serve

# 全局安装serve
npm install -g serve

# 进入打包目录
cd dist/build/h5

# 启动本地服务器
serve -s . -p 8080

然后在浏览器中访问http://localhost:8080即可预览H5应用。

部署H5到线上的方法

1. 静态资源托管

将打包后的H5应用部署到静态资源托管平台,如:

  • 阿里云OSS
  • 腾讯云COS
  • 七牛云
  • GitHub Pages
  • Netlify
  • Vercel

以阿里云OSS为例:

  1. 登录阿里云OSS控制台,创建一个存储空间
  2. 配置存储空间的访问权限为"公共读"
  3. 使用工具(如ossutil)将/dist/build/h5目录下的所有文件上传到存储空间
  4. 配置自定义域名(可选)
  5. 通过自定义域名或Bucket域名访问H5应用

2. 使用Nginx部署

如果使用自己的服务器,可以通过Nginx部署H5应用:

  1. 将打包后的文件上传到服务器的指定目录(如/var/www/html
  2. 配置Nginx:
server {
    listen 80;
    server_name yourdomain.com;
    root /var/www/html;
    index index.html;
    
    # 处理单页应用的路由
    location / {
        try_files $uri $uri/ /index.html;
    }
    
    # 可选:配置HTTPS
    # listen 443 ssl;
    # ssl_certificate /path/to/cert.pem;
    # ssl_certificate_key /path/to/key.pem;
}
  1. 重启Nginx服务:
sudo nginx -s reload

3. 使用CI/CD自动化部署

可以使用GitHub Actions、Jenkins等CI/CD工具实现自动化部署:

以GitHub Actions为例:

  1. 在GitHub仓库中创建.github/workflows/deploy.yml文件:
name: Deploy to Production

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    
    - name: Setup Node.js
      uses: actions/setup-node@v2
      with:
        node-version: '14'
        
    - name: Install dependencies
      run: npm install
      
    - name: Build
      run: npm run build:h5
      
    - name: Deploy to Aliyun OSS
      uses: aliyun/ossutil-action@master
      with:
        endpoint: 'https://oss-cn-hangzhou.aliyuncs.com'
        access-key-id: ${{ secrets.ALIYUN_ACCESS_KEY_ID }}
        access-key-secret: ${{ secrets.ALIYUN_ACCESS_KEY_SECRET }}
        bucket: 'your-bucket-name'
        source: './dist/build/h5'
        destination: '/'
  1. 在GitHub仓库的Settings > Secrets中添加ALIYUN_ACCESS_KEY_IDALIYUN_ACCESS_KEY_SECRET两个Secret
  2. 每次推送代码到main分支时,会自动触发构建和部署流程

常见问题与解决方案

1. 单点登录跨域问题

问题:在H5环境下,跨域请求被浏览器拦截。

解决方案

  • 在开发环境中,通过配置manifest.json中的代理解决
  • 在生产环境中,后端需要配置CORS,允许前端域名访问

2. H5路由刷新404问题

问题:使用history模式时,刷新页面出现404错误。

解决方案

  • 改用hash模式路由
  • 或者在后端配置所有请求都返回index.html

3. Token存储问题

问题:Token存储在localStorage中,可能存在安全风险。

解决方案

  • 对于敏感应用,可以考虑使用HttpOnly的Cookie存储Token
  • 或者使用更安全的存储方案,如sessionStorage

总结

本文详细介绍了如何在uniapp中实现单点登录功能,以及如何将uniapp项目打包成H5应用并部署到线上。通过单点登录,可以提升用户体验,减少重复登录的麻烦;而将H5应用部署到线上,可以让用户随时随地访问应用。

在实际开发过程中,还需要根据具体业务需求进行调整和优化,例如增加Token刷新机制、处理异常情况、优化性能等。希望本文能够帮助到正在使用uniapp进行开发的开发者们。觉得有用就点个关注!我会持续分享更多实用工具和效率技巧。想直接体验?各类免费、开箱即用的在线工具,都在我的【星点工具箱】网站等你来玩!

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐