实现目标:通过微信H5接入微信获取openid和unionid、用户头像,以及实现登录。
MySQL代码:
CREATE TABLE `xn_user` (
`id` int NOT NULL AUTO_INCREMENT,
`tno` int DEFAULT NULL COMMENT '编号',
`username` char(25) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '账号',
`password` char(100) CHARACTER SET utf16 COLLATE utf16_general_ci DEFAULT NULL COMMENT '密码',
`realname` char(25) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '姓名',
`phone` char(20) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '电话',
`city_id` int NOT NULL DEFAULT '0' COMMENT '省份ID',
`area_id` int NOT NULL DEFAULT '0' COMMENT '市区ID',
`street_id` int DEFAULT '0' COMMENT '县ID',
`status` int DEFAULT '0',
`create_time` int DEFAULT NULL,
`update_time` int DEFAULT NULL,
`school_id` int DEFAULT NULL COMMENT '学校ID',
`last_login_ip` varchar(16) DEFAULT NULL,
`last_login_time` int DEFAULT '0',
`role_id` int DEFAULT NULL COMMENT '角色ID',
`token` varchar(255) DEFAULT NULL COMMENT 'token',
`ttl` int DEFAULT NULL COMMENT '过期时间',
`openid` char(50) DEFAULT NULL,
`unionid` char(50) DEFAULT NULL,
`headimgurl` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=498 DEFAULT CHARSET=utf8mb3;
PHP代码:
Login/index.php
public function index(){
$data = Request::param();
$username = trim($data['pn']);
$password = trim($data['pwd']);
$openid = $data['openid'];
$unionid = $data['unionid'];
$headimgurl = $data['headimgurl'];
if(!$username){
return show(0,'请输入登录的手机号码',[]);
}
if(!$password){
return show(0,'请输入登录密码',[]);
}
$admin_data = Teacher::where([
'phone' => $username,
'password' => gt_encrypt($password),
])->field('id,username,phone,realname,status,last_login_ip,last_login_time,city_id,area_id,street_id,school_id,role_id,openid,unionid,headimgurl')->find();
if( empty($admin_data) ) {
return show(0,'手机号或密码不正确');
}
if($admin_data['status']!=1) {
return show(0,'您的账户处于禁用状态');
}
if($openid){
//如果openid不存在,则可以绑定账号
if(!$admin_data['openid']){
$admin_data->openid = $openid;
$admin_data->unionid = $unionid;
$admin_data->headimgurl = $headimgurl;
$admin_data->save();
}
}
$token = Auth::getInstance(['uid'=>$admin_data['id']])->setToken()->getToken();
$data = [
'username'=>$admin_data['phone'],
'realname'=>$admin_data['realname'],
'uid'=>$admin_data['id'],
'school_id'=>$admin_data['school_id'],
'role_id'=>$admin_data['role_id'],
'role_name'=>'角色简称',
'role_title'=>'角色名称',
'school_name'=>get_school_name($admin_data['school_id']),
'token'=>$token,
'openid'=>$admin_data['openid'],
'headimgurl'=>$admin_data['headimgurl']?:Config::get('custom.http_url').'static/headimg.png'
];
return show(1,'登录成功',$data);
}
Template代码
<form @submit="loginNow" class="grace-form" style="margin-top:80rpx;">
<view class="grace-form-item grace-border-b">
<text class="grace-form-label">手机号码text>
<view class="grace-form-body"><input type="text" class="grace-form-input" name="pn" placeholder="请输入手机号" />view>
view>
<view class="grace-form-item grace-border-b">
<text class="grace-form-label">登录密码text>
<view class="grace-form-body"><input type="password" class="grace-form-input" name="pwd" placeholder="请输入登录密码" />view>
view>
<view class="grace-margin-top">
<button form-type="submit" type="primary" class="grace-button grace-border-radius grace-gtbg-blue">
登录
<text class="grace-icons icon-arrow-right">text>
button>
view>
form>
Vue代码
<script>
import gracePage from '../../graceUI/components/gracePage.vue';
var graceChecker = require('../../graceUI/jsTools/graceChecker.js');
export default {
data() {
return {
phoneno: '',
headimgurl:'',
openid:'',
unionid:'',
};
},
onLoad() {
var localData = uni.getStorageSync('localData');
if (localData) {
this.$router.push({ path: '/pages/index/index' });
}
//开启之后只能是公众号访问
this.loginWithWx();
},
methods: {
loginWithWx: function() {
if (!uni.getStorageSync('openid') || uni.getStorageSync('openid') == undefined ) {
this.getWxUserInfoCode();
}
},
loginNow: function(e) {
// 表单验证
var rule_sms = [
{ name: 'pn', checkType: 'phoneno', errorMsg: '请填写正确的手机号' },
];
var rule_pwd = [
{ name: 'pn', checkType: 'string', checkRule: '4,16', errorMsg: '请填写正确的手机号' }
];
var formData = e.detail.value;
var checkRes = graceChecker.check(formData, rule_pwd);
// 验证通过
if (checkRes) {
uni.showLoading({
title: '正在登录....'
});
this.$sendRequest({
url: 'login',
data: {
pn: formData.pn,
pwd: formData.pwd,
openid: this.openid,
unionid: this.unionid,
headimgurl: this.headimgurl,
},
method: 'POST',
dataType: 'json', // 返回数据格式,
header: {
'Content-Type': 'application/x-www-form-urlencoded'
},
success: res => {
uni.hideLoading();
if (res.data.code == 1) {
uni.showToast({
title: res.data.msg,
icon: 'none',
duration: 2000,
success: () => {
uni.setStorageSync('localData', res.data.data);
this.$router.push({ path: '/pages/index/index' });
}
});
} else {
uni.showToast({ title: res.data.msg, icon: 'none' });
}
}
});
} else {
uni.hideLoading();
uni.showToast({ title: graceChecker.error, icon: 'none' });
}
},
//微信公众号登录
getWxUserInfoCode() {
var code = this.getUrlParam('code'); // 截取路径中的code,如果没有就去微信授权,如果已经获取到了就直接传code给后台获取openId
var local = encodeURIComponent('https://你的h5地址/h5/#/pages/login/login');
let appid = 'appid';
if (code == null || code === '') {
window.location.href =
'https://open.weixin.qq.com/connect/oauth2/authorize?appid='+appid+'&redirect_uri='+local+'&response_type=code&scope=snsapi_base&connect_redirect=1&state=#wechat_redirect';
} else {
this.getOpenId(code); //把code传给后台获取用户信息
}
},
getOpenId(code) {
var _this = this;
_this.$sendRequest({
url: 'wechat/get_open_id',
data: {
code: code
},
method: 'get',
dataType: 'json', // 返回数据格式,
header: {
'Content-Type': 'application/x-www-form-urlencoded'
},
success: res => {
// console.log(res.data);
if (res.data.code == 1) {
uni.setStorageSync('openid', res.data.data.openid);
uni.setStorageSync('unionid', res.data.data.unionid);
uni.setStorageSync('headimgurl', res.data.data.headimgurl);
_this.openid = res.data.data.openid,
_this.unionid = res.data.data.unionid,
_this.headimgurl = res.data.data.headimgurl
}
}
});
},
// 解析URL 参数
getUrlParam(name) {
let reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)');
let r = window.location.search.substr(1).match(reg);
if (r != null) {
return unescape(r[2]);
}
return null;
}
},
components: {
gracePage
}
};
</script>
wechat/get_open_id
namespace app\api\controller;
use app\common\controller\Base;
use EasyWeChat\Factory;
use think\App;
use think\facade\Config;
use think\facade\Request;
class Wechat extends Base
{
public function __construct(App $app){
parent::__construct($app);
$this->conf = \think\facade\Config::load("cfg/base", 'base');
}
//微信相关
public function get_open_id(){
$code = Request::param('code');
if($code){
$access_token_info = self::get_access_token($code);
$user_info = self::get_user_info($access_token_info['access_token'],$access_token_info['openid']);
return show(1,'success',$user_info);
}else{
return show(0,'Code is null');
}
}
//通过 code 换取网页授权access_token
public function get_access_token($code){
$url = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid='.$this->conf['appid'].'&secret='.$this->conf['appsecrect'].'&code='.$code.'&grant_type=authorization_code';
$curlRes = postDataCurl($url,[]);
return json_decode($curlRes,true);
}
public function get_user_info($access_token,$openid){
$url = 'https://api.weixin.qq.com/sns/userinfo?access_token='.$access_token.'&openid='.$openid.'&lang=zh_CN';
$curlRes = postDataCurl($url,[]);
return json_decode($curlRes,true);
}
}
如果提示:api unauthorized 48001错误,那就需要把 scope=snsapi_base 改为 scope=snsapi_userinfo