Расширение функции входа в систему при сканировании кода WeChat на основе реализации привязки Ruoyi framework-WeChat.
Расширение функции входа в систему при сканировании кода WeChat на основе реализации привязки Ruoyi framework-WeChat.

Предисловие

Недавно я изучал знания, связанные с Java, и мой друг посоветовал взглянуть на фреймворк Ruoyi, поэтому я расширил функцию входа в WeChat на основе фреймворка Ruoyi (отдельные версии внешнего и внутреннего интерфейса).

Идеи реализации

Стандартный вход в систему с помощью скан-кода требует подачи заявки на учетную запись открытой платформы WeChat и наличия утвержденного приложения на веб-сайте, то есть: входа в приложение WeChat на веб-сайте, что является громоздким процессом. Во избежание проблем операция входа в систему выполняется на основе авторизации официальной веб-страницы учетной записи WeChat. Вы также можете изучить процесс сканирования QR-кода для входа в систему.

Чтобы отсканировать QR-код для входа на основе авторизации веб-страницы официального аккаунта, нам нужно только подготовить официальную учетную запись (требуется сертифицированная сервисная учетная запись или требуется прямая заявка на тестовую официальную учетную запись).

Поскольку платформа Ruoyi уже имеет собственную таблицу пользователей, вход для сканирования кода здесь необходимо разработать в двух частях:

  • Привязка пользователя Ruoyi WeChat
  • Пользователь Ruoyi сканирует QR-код, чтобы войти через WeChat

Процесс реализации

Разработка привязки WeChat

Сценарий привязки WeChat заключается в том, что нам нужно сначала войти в систему Ruoyi, затем открыть страницу личной информации, нажать кнопку привязки WeChat на странице, чтобы отобразить QR-код, а затем отсканировать код с помощью WeChat на мобильном телефоне. телефон для завершения привязки.

Процесс сканирования кода для части привязки примерно следующий:

После нажатия кнопки привязки WeChat на ПК ключ пользователя получается из текущего токена входа. На основе ссылки для объединения ключа пользователя на передней панели появляется QR-код. Адрес QR-кода (со сгенерированным ключом пользователя). — это ссылка для авторизации веб-страницы. WeChat. После сканирования кода для его открытия вы можете напрямую авторизовать официальную веб-страницу учетной записи. После получения кода вы будете перенаправлены на внутренний интерфейс, чтобы получить openid пользователя и обновить его. пользовательскую таблицу для завершения привязки.

На основе этого процесса и в сочетании с платформой Ruoyi нам необходимо разработать следующие интерфейсы и изменить страницу:

  • Привязка OpenID WeChat
  • Статус привязки запроса uuid пользователя и openid
  • Добавить привязку WeChat к странице личной информации Функция

Поскольку нам нужен доступ к информации пользователей WeChat, нам нужно спросить sys_user В таблицу пользователей добавляются два поля: wx_nick_name, openid.

Разработка привязки WeChat openid

1.существоватьruoyi-admin/src/main/java/com/ruoyi/web/controller/common/Создать новый нижеWxController.javaИспользуется для обработки запросов, связанных с WeChat.。然后существоватьWxControllerДобавьте WeChat вопенидбиндингметод:

Язык кода:java
копировать
/**
 * Получить открытый идентификатор
 */
@GetMapping("/bind-openid")
public AjaxResult getOpenid(@RequestParam("code") String code, @RequestParam("key") String key) throws IOException
{
    AjaxResult ajax = AjaxResult.success();
    SysUser u = userService.getOpenid(code);
    String openid = u.getOpenid();
    LoginUser userCache = redisCache.getCacheObject(CacheConstants.LOGIN_TOKEN_KEY + key);
    SysUser user = new SysUser();
    user.setUserId(userCache.getUserId());
    user.setOpenid(openid);
    user.setWxNickName(u.getWxNickName());
    userService.updateUserOpenid(user);

    ajax.put("openid", openid);
    ajax.put("wxnickname", u.getWxNickName());
    return ajax;
}

Этот метод в основном завершает прием кода авторизации общедоступной учетной записи WeChat, запрашивает интерфейс WeChat для получения openid пользователя, получает идентификатор пользователя из кэша повторного отображения информации для входа текущего пользователя, а затем обновляет openid пользователя WeChat в таблице пользователей для завершения. привязка.

Для удобства код перенаправляется непосредственно на адрес интерфейса.

2.существоватьruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java Добавьте WeChat в code Получить пользователя openid метод:

Язык кода:java
копировать
/**
 * по коду Получить пользователяopenid
 *
 * @param code Код авторизации веб-страницы официального аккаунта WeChat
 * @return useropenid
 */
@Override
public SysUser getOpenid(String code) {
    RestTemplate restTemplate = new RestTemplate();
    JSONObject jsonData = null;

    // Создайте URL-адрес для получения access_token
    String url = "https://api.weixin.qq.com/sns/oauth2/access_token?"
            + "appid=" + appId
            + "&secret=" + secret
            + "&code=" + code
            + "&grant_type=authorization_code";

    System.out.println("url: " + url);
    ResponseEntity<String> responseEntity = restTemplate.getForEntity(url, String.class);

    System.out.println("responseEntity: " + responseEntity);
    if (responseEntity.getStatusCodeValue() == 200 && responseEntity.getBody() != null) {
        jsonData = JSONObject.parseObject(responseEntity.getBody());
    }

    String userInfoUrl = "https://api.weixin.qq.com/sns/userinfo?lang=zh_CN"
            + "&access_token=" + jsonData.getString("access_token")
            + "&openid=" + jsonData.getString("openid");

    ResponseEntity<String> responseUserEntity = restTemplate.getForEntity(userInfoUrl, String.class);
    if (responseUserEntity.getStatusCodeValue() == 200 && responseUserEntity.getBody() != null) {
        JSONObject jsonUserData = JSONObject.parseObject(new String(responseUserEntity.getBody().getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8));
        System.out.println("jsonUserData: " + jsonUserData);
        SysUser user = new SysUser();
        user.setOpenid(jsonUserData.getString("openid"));
        user.setWxNickName(jsonUserData.getString("nickname"));
        return user;
    }

    return null;
}

Поскольку здесь используются официальное приложение и секрет учетной записи, нам необходимо ruoyi-admin/src/main/resources/application.yml Добавьте соответствующую конфигурацию в файл конфигурации:

Язык кода:yml
копировать
# Официальная конфигурация аккаунта
wechat:
  # Идентификатор приложения
  appid:
  # ключ приложения
  secret:

После добавления конфигурации вам необходимо SysUserServiceImpl Добавьте соответствующие частные атрибуты в:

Язык кода:java
копировать
@Value("${wechat.appid}")
private String appId;

@Value("${wechat.secret}")
private String secret;

3.существоватьruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.javaДобавьте изменения вuseropenidизметод:

Язык кода:java
копировать
/**
 * Изменить идентификатор пользователя
 *
 * @param user Информация о пользователе
 * @return результат
 */
@Override
public int updateUserOpenid(SysUser user)
{
    return userMapper.updateUser(user);
}

Нам нужно быть здесь ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java Добавьте соответствующее объявление метода в:

Язык кода:java
копировать
/**
 * редактировать Информацию о пользователе
 * 
 * @param user Информация о пользователе
 * @return результат
 */
public int updateUser(SysUser user);

и в ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml Дополните соответствующий SQL-код обновления, то есть добавьте решение об обновлении OpenID и псевдонима WeChat в установленную часть обновленного пользовательского SQL-запроса:

Язык кода:xml
копировать
<update id="updateUser" parameterType="SysUser">
 	...
	<if test="openid != null and openid != ''">openid = #{openid},</if>
	<if test="wxNickName != null and wxNickName != ''">wx_nick_name = #{wxNickName},</if>
	...
</update>

Поскольку была добавлена ​​информация об открытом идентификаторе WeChat и псевдониме.,Поэтому его необходимо изменитьruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.javaдокумент,Добавьте псевдоним WeChat и атрибуты openid:

Язык кода:java
копировать
/** Никнейм пользователя WeChat */
@Excel(name = "Никнейм пользователя WeChat")
private String wxNickName;

/** openid */
@Excel(name = "openid")
private String openid;

public String getOpenid()
{
    return openid;
}

public void setOpenid(String openid)
{
    this.openid = openid;
}

public String getWxNickName()
{
    return wxNickName;
}

public void setWxNickName(String wxNickName)
{
    this.wxNickName = wxNickName;
}

Таким образом, мы завершили разработку интерфейса привязки openid WeChat.

Статус привязки запроса uuid пользователя и openid

Следующим шагом является запрос информации о привязке WeChat.

1.существоватьruoyi-admin/src/main/java/com/ruoyi/web/controller/common/WxController.javaДополнительные домохозяйстваuuidЗапросopenidметод:

Язык кода:java
копировать
/**
 * Вошедший в систему пользователь uuid запрос openid
 */
@GetMapping("/uuid")
public AjaxResult getCode(@RequestParam("uuid") String uuid) throws IOException
{
    AjaxResult ajax = AjaxResult.success();
    LoginUser userLogin = redisCache.getCacheObject(CacheConstants.LOGIN_TOKEN_KEY + uuid);
    SysUser user = userService.selectUserById(userLogin.getUserId());
    System.out.println("user-openid: " + user.getOpenid());
    System.out.println("user-wxnickname: " + user.getWxNickName());
    if (user.getOpenid() != null) {
        ajax.put("openid", user.getOpenid());
        ajax.put("wxnickname", user.getWxNickName());
    }
    ajax.put("status", user.getOpenid() != null ? 1: 0);
    return ajax;
}

2.существоватьruoyi-system/src/main/resources/mapper/system/SysUserMapper.xmlизselectUserVoЗапросsqlСреднее сложениеopenid、Запрос псевдонима WeChat:

Язык кода:xml
копировать
<sql id="selectUserVo">
select  ...,
        u.openid, u.wx_nick_name,
        ...
        from sys_user u
</select>

Таким образом, запрашиваемая информация о пользователе будет содержать связанную информацию WeChat.

Изменение разрешения доступа к интерфейсу

Поскольку пользователь не вошел в систему на мобильном телефоне при сканировании кода для привязки, все ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java Добавьте интерфейс привязки в список разрешенных:

Язык кода:java
копировать
requests.antMatchers("/login", "/register", "/captchaImage", "/bind-openid").permitAll()

На этом этапе интерфейс привязки, который необходимо разработать, был изменен. Давайте изменим страницу.

Добавить привязку WeChat к странице личной информации
  1. Добавлены зависимости внешнего проекта. Потому что для сканирования кода требуется создание QR-кода.,Так вот для удобства использования фронтенд плагинаvue-qrгенерировать,существовать前端项目根目录npm install vue-qrВот и все。
  2. Добавить интерфейс。существоватьruoyi-ui/src/api/system/user.jsСреднее сложение我们上面写好из Запрособязательность状态接口:
Язык кода:js
копировать
export function getUUid(data) {
    return request({
        url: '/uuid?uuid=' + data.uuid,
        method: 'get'
    })
}

3.Модификация страницы。Изменить страницу личной информацииruoyi-ui/src/views/system/user/profile/userInfo.vue

3.1 Добавьте кнопку привязки WeChat и всплывающее окно:

Язык кода:html
копировать
<el-form-item label="Вичат">
    <span class="mr10">{{form.wxnickname || 'Не связан'}}</span>
    <el-button v-if="form.openid == '' || form.openid == null" :loading="bindloading" size="medium" type="primary" class="btn" @click.stop="wxBind()">绑 定</el-button>
    <el-button v-else :loading="bindloading" size="medium" type="primary" class="btn" @click.stop="unBind()">解
        绑</el-button>
</el-form-item>

<el-dialog title="Привязать WeChat" custom-class="bind-dialog" class="new-common-dialog" :visible.sync="bindWxVisible" :close-on-click-modal="false" :close-on-press-escape="false" @close="wxLoginClose" width="320px">
    <div class="qr-code">
        <vue-qr :text="qrUrl" :size="280"></vue-qr>
    </div>
</el-dialog>

3.2 Импортируйте зависимые интерфейсы и связанный метод:

Язык кода:js
копировать
import {
    updateUserProfile,
    getUUid
} from "@/api/system/user";
import {
    getToken
} from '@/utils/auth'
import vueQr from 'vue-qr'

3.3. Ссылка на компонент QR-кода:

Язык кода:js
копировать
components: {
    vueQr,
},

3.4 Новые атрибуты в данных:

Язык кода:js
копировать
timer: null,
    bindWxVisible: false,
    bindloading: false,
    qrUrl: '',

3.5 Измените метод мониторинга пользователей, чтобы на странице отображался псевдоним WeChat:

Язык кода:js
копировать
user: {
    handler(user) {
        console.log('user', this.user)
        if (user) {
            this.form = {
                nickName: user.nickName,
                wxnickname: user.wxNickName,
                phonenumber: user.phonenumber,
                email: user.email,
                sex: user.sex,
                openid: user.openid
            };
        }
    },
    immediate: true
}

3.6 Добавьте соответствующую информацию о привязке WeChat:

Язык кода:js
копировать
 wxBind() {
    let token = getToken()
    const key = JSON.parse(atob(token.split('.')[1]))['login_user_key'];
    const redirect_uri = `http://web-hub.uat.kai12.cn/auth.html?backUrl=${локальный IP}:8080/bind-openid?key=${key}`
    const codeUrl = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=Официальный аккаунтappid&redirect_uri=${encodeURIComponent(redirect_uri)}&response_type=code&scope=snsapi_userinfo&state=123456#wechat_redirect`
    this.qrUrl = codeUrl
    console.log(this.qrUrl)
    this.bindWxVisible = true
    let that = this
    this.timer = setInterval(function() {
        getUUid({
                uuid: key
            })
            .then((res) => {
                console.log(res)
                if (res.status === 1) {
                    that.bindWxVisible = false
                    that.form.openid = res.openid
                    that.form.wxnickname = res.wxnickname
                    that.$message({
                        type: 'success',
                        message: «Операция прошла успешно»,
                    })
                    clearTimeout(this.timer)
                }
            })
            .catch((err) => {
                clearTimeout(that.timer)
            })
    }, 1000)
},
wxLoginClose() {
    this.timer && clearTimeout(this.timer)
},

В основном это делается путем получения токена, кэшированного браузером, и его анализа из файла пользователя Ruoyi. login_user_key Чтобы добиться привязки ассоциации.

На этом весь процесс привязки WeChat примерно завершен.

Проверьте это:

Ссылки

boy illustration
Неразрушающее увеличение изображений одним щелчком мыши, чтобы сделать их более четкими артефактами искусственного интеллекта, включая руководства по установке и использованию.
boy illustration
Копикодер: этот инструмент отлично работает с Cursor, Bolt и V0! Предоставьте более качественные подсказки для разработки интерфейса (создание навигационного веб-сайта с использованием искусственного интеллекта).
boy illustration
Новый бесплатный RooCline превосходит Cline v3.1? ! Быстрее, умнее и лучше вилка Cline! (Независимое программирование AI, порог 0)
boy illustration
Разработав более 10 проектов с помощью Cursor, я собрал 10 примеров и 60 подсказок.
boy illustration
Я потратил 72 часа на изучение курсорных агентов, и вот неоспоримые факты, которыми я должен поделиться!
boy illustration
Идеальная интеграция Cursor и DeepSeek API
boy illustration
DeepSeek V3 снижает затраты на обучение больших моделей
boy illustration
Артефакт, увеличивающий количество очков: на основе улучшения характеристик препятствия малым целям Yolov8 (SEAM, MultiSEAM).
boy illustration
DeepSeek V3 раскручивался уже три дня. Сегодня я попробовал самопровозглашенную модель «ChatGPT».
boy illustration
Open Devin — инженер-программист искусственного интеллекта с открытым исходным кодом, который меньше программирует и больше создает.
boy illustration
Эксклюзивное оригинальное улучшение YOLOv8: собственная разработка SPPF | SPPF сочетается с воспринимаемой большой сверткой ядра UniRepLK, а свертка с большим ядром + без расширения улучшает восприимчивое поле
boy illustration
Популярное и подробное объяснение DeepSeek-V3: от его появления до преимуществ и сравнения с GPT-4o.
boy illustration
9 основных словесных инструкций по доработке академических работ с помощью ChatGPT, эффективных и практичных, которые стоит собрать
boy illustration
Вызовите deepseek в vscode для реализации программирования с помощью искусственного интеллекта.
boy illustration
Познакомьтесь с принципами сверточных нейронных сетей (CNN) в одной статье (суперподробно)
boy illustration
50,3 тыс. звезд! Immich: автономное решение для резервного копирования фотографий и видео, которое экономит деньги и избавляет от беспокойства.
boy illustration
Cloud Native|Практика: установка Dashbaord для K8s, графика неплохая
boy illustration
Краткий обзор статьи — использование синтетических данных при обучении больших моделей и оптимизации производительности
boy illustration
MiniPerplx: новая поисковая система искусственного интеллекта с открытым исходным кодом, спонсируемая xAI и Vercel.
boy illustration
Конструкция сервиса Synology Drive сочетает проникновение в интрасеть и синхронизацию папок заметок Obsidian в облаке.
boy illustration
Центр конфигурации————Накос
boy illustration
Начинаем с нуля при разработке в облаке Copilot: начать разработку с минимальным использованием кода стало проще
boy illustration
[Серия Docker] Docker создает мультиплатформенные образы: практика архитектуры Arm64
boy illustration
Обновление новых возможностей coze | Я использовал coze для создания апплета помощника по исправлению домашних заданий по математике
boy illustration
Советы по развертыванию Nginx: практическое создание статических веб-сайтов на облачных серверах
boy illustration
Feiniu fnos использует Docker для развертывания личного блокнота Notepad
boy illustration
Сверточная нейронная сеть VGG реализует классификацию изображений Cifar10 — практический опыт Pytorch
boy illustration
Начало работы с EdgeonePages — новым недорогим решением для хостинга веб-сайтов
boy illustration
[Зона легкого облачного игрового сервера] Управление игровыми архивами
boy illustration
Развертывание SpringCloud-проекта на базе Docker и Docker-Compose