签到鉴权,django开荒微信小程序后端登入和鉴权

作者: 韦德国际1946国际网址  发布:2019-05-28

前言

一.微信小主次与常见web后端差异

登六鉴权:

OAuth2.0鉴权

  • 万众号能够通过微信网页授权机制,来收获用户中央音讯,进而完成职业逻辑。
  • 网页授权获取用户宗旨音讯
    点击修改设置授权回调域名
在微信公众号请求用户网页授权之前,开发者需要先到公众平台官网
中的开发者中心页配置授权回调域名。请注意,这里填写的是域名
(是一个字符串),而不是URL,因此请勿加[http://等协议头;]
(http://xn--;-nv8a14pdn5bver/)2、授权回调域名配置规范为
全域名,比如需要网页授权的域名为:www.qq.com,配置以后此域
名下面的页面[http://www.qq.com/music.html]
(http://www.qq.com/music.html) 、 
[http://www.qq.com/login.html]
(http://www.qq.com/login.html) 都可以进行OAuth2.0鉴权。但
[http://pay.qq.com](http://pay.qq.com/) 、 
[http://music.qq.com](http://music.qq.com/) 、 
[http://qq.com无法进行OAuth2.0鉴权](http://qq.xn--
comoauth2-735sh62dwk9eysua.xn--0-k76bu98j/)3、如果公众
号登录授权给了第三方开发者来进行管理,则不必做任何设置,由第
三方代替公众号实现网页授权即可

<?php
/*
本文件位置
*/
$redirect_url= "http://www.camera.0fees.us/index.php";
/*
URL
*/
$url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx6292681b13329528&redirect_uri=http://israel.duapp.com/weixin/oauth2_openid.php&response_type=code&scope=snsapi_base&state=1#wechat_redirect";

$code = $_GET["code"];
$userinfo = getUserInfo($code);

function getUserInfo($code)
{
  $appid = "wxb202efbc9c76046a";
  $appsecret = "b8d396c379cc2b2277c4f1c062365f3a";

    //oauth2的方式获得openid
  $access_token_url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=$appid&secret=$appsecret&code=$code&grant_type=authorization_code";
  $access_token_json = https_request($access_token_url);
  $access_token_array = json_decode($access_token_json, true);
  $openid = $access_token_array['openid'];

    //非oauth2的方式获得全局access token
    $new_access_token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$appid&secret=$appsecret";
    $new_access_token_json = https_request($new_access_token_url);
  $new_access_token_array = json_decode($new_access_token_json, true);
  $new_access_token = $new_access_token_array['access_token'];

    //全局access token获得用户基本信息
    $userinfo_url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=$new_access_token&openid=$openid";
  $userinfo_json = https_request($userinfo_url);
  $userinfo_array = json_decode($userinfo_json, true);
  return $userinfo_array;
}

function https_request($url)
{
  $curl = curl_init();
  curl_setopt($curl, CURLOPT_URL, $url);
  curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
  curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
  curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
  $data = curl_exec($curl);
  if (curl_errno($curl)) {return 'ERROR '.curl_error($curl);}
  curl_close($curl);
  return $data;
}
?>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
  <HEAD><TITLE>OAuth2.0认证</TITLE>
    <META charset=utf-8>
    <META name=viewport content="width=device-width, user-scalable=no, initial-scale=1">
    <LINK rel="stylesheet" href="css/jquery.mobile-1.3.2.css">
    <SCRIPT src="js/jquery-1.10.2.js"></SCRIPT>
    <SCRIPT src="js/jquery.mobile-1.3.2.js"></SCRIPT>
  </HEAD>

  <BODY>
    <script type="text/javascript">
      document.addEventListener('WeixinJSBridgeReady', function onBridgeReady() {
        WeixinJSBridge.call('hideOptionMenu');
      });
      document.addEventListener('WeixinJSBridgeReady', function onBridgeReady() {
        WeixinJSBridge.call('hideToolbar');
      });
    </script>
    <div data-role="page" id="page1">
      <div data-role="content">
        <div style=" text-align:center">
          <img style="width: 99%; height: %" src="<?php echo $userinfo["headimgurl"];?>">
        </div>
        <UL data-role="listview" data-inset="true">
          <LI>
            <P>
              <div class="fieldcontain">
                <label for="subscribe">是否关注</label>
                <input name="subscribe" id="subscribe" value="<?php echo $userinfo["subscribe"];?>" type="text" >
              </div>
              <div class="fieldcontain">
                <label for="openid">OpenID</label>
                <input name="openid" id="openid" value="<?php echo $userinfo["openid"];?>" type="text" >
              </div>
              <div class="fieldcontain">
                <label for="nickname">昵称</label>
                <input name="nickname" id="nickname" value="<?php echo $userinfo["nickname"];?>" type="text" >
              </div>
              <div class="fieldcontain">
                <label for="sex">性别</label>
                <input name="sex" id="sex" value="<?php echo $userinfo["sex"];?>" type="text" >
              </div>
              <div class="fieldcontain">
                <label for="country">国家</label>
                <input name="country" id="country" value="<?php echo $userinfo["country"];?>" type="text" >
              </div>
              <div class="fieldcontain">
                <label for="province">省份</label>
                <input name="province" id="province" value="<?php echo $userinfo["province"];?>" type="text" >
              </div>
              <div class="fieldcontain">
                <label for="city">城市</label>
                <input name="city" id="city" value="<?php echo $userinfo["city"];?>" type="text" >
              </div>
              <div class="fieldcontain">
                <label for="subscribe_time">关注时间</label>
                <input name="subscribe_time" id="subscribe_time" value="<?php echo $userinfo["subscribe_time"];?>" type="text" >
              </div>
            </P>
          </LI>
        </UL>
      </div>
      <div data-theme="a" data-role="footer" data-position="fixed">
        <h3>方倍工作室</h3>
      </div>
    </div>

  </BODY>
</HTML>

为了有利于小程序行使使用微信登入态举行授权登入,微信小程序提供了登6授权的绽开接口。乍1看文书档案,认为文书档案上讲的可怜有道理,可是落实起来又真的是摸不着头脑,不清楚怎么着保管和爱惜登入态。本文就来手把手的教会大家在作业里什么对接和掩护微信登入态,下边话十分少说了,来一同看看详细的牵线吧。

1.小程序端没有cookie只要本地存款和储蓄

2.小程序必须使用https,在该地开采者工具得以先屏蔽

  1. 用户名 密码 登6请求
  2. 后台接受登陆请求,生成ToKen(用户名/密码正确) 再次回到token
  3. 恳请其余api 都带上token,后台校验token是不是存在/过期

连接流程

二.微信小程序登六和鉴权

后台代码如下:
登录/登出 --------------
@RestController
@RequestMapping
class AuthController {

那边官方文书档案上的流程图已经足足清晰,大家平素就该图张开详述和互补。

小程序有个别应用场景不适合利用django内置的user登入,因而须要自定义的报到验证措施,使用jwt的章程是最适合的,不过djangodjangorestframework-jwt和django-jwt都与内置的user耦合由此不适用,笔者这里用pyjwt的艺术重写三个签到情势供参谋。

@Autowired
private lateinit var tokenService: TokenService
@Autowired
private lateinit var appUserService: AppUserService

图片 1 

叁.代码示例

@PostMapping(value = ["/auth/login"])
fun login(username: String, password: String,
request: HttpServletRequest): RestResponse<Any> {
val predicate = Predicate.eq("username", username).eq("password", password)
val user = appUserService.findOne(predicate) ?: return RestResponse(壹, "用户不存在")
// 生成八个 token,保存用户登陆状态
val tokenModel = tokenService.createToken(user.userId, user.nickname, Utils.getIp(request))
return RestResponse(0, mapOf(
"user" to user,
"token" to tokenModel.token,
"roles" to arrayOf("admin")))
}
签到鉴权,django开荒微信小程序后端登入和鉴权。@PostMapping(value = ["/auth/logout"])
fun logout(@RequestAttribute tokenModel: TokenModel): RestResponse<Any> {
tokenService.deleteToken(tokenModel.token)
return RestResponse(0, "success")
}

率先大家看来那张图,鲜明会专注到小程序开始展览通讯交互的不仅是小程序前端和大家团结的服务端,微信第2方服务端也涉足其间,那么微信服务端在里边扮演着怎么着的剧中人物吗?大家一道来串贰遍登陆鉴权的流程就知道了。

1.小程序端代码

}
-----配置拦截器---------------------------
WebAppConfigurer.kt
override fun addInterceptors(registry: InterceptorRegistry) {
registry.addInterceptor(authInterceptor())
.excludePathPatterns("/auth/**")
.excludePathPatterns("/rest/**")
}

1. 调用wx.login生成code

在微信登入供给用button获取用户音信。

@Bean
fun authInterceptor(): AuthInterceptor {
return AuthInterceptor()
}
拦截器-------------------------------
@Component
class AuthInterceptor : HandlerInterceptorAdapter() {

wx.login()这几个API的功能就是为当前用户生成二个临时的记名凭证,那些有的时候登入凭证的限期唯有伍分钟。大家获得那些登6凭证后就足以开始展览下一步操作:获取 openid 和 session_key

<button open-type="getUserInfo" type="primary" lang="zh_CN" bindgetuserinfo="onGotUserInfo">授权</button>

@Autowired
private lateinit var tokenService: TokenService

wx.login({
 success: function(loginRes) {
 if (loginRes.code) {
  // example: 081LXytJ1Xq1Y40sg3uJ1FWntJ1LXyth
 }
 }
});

倡议呼吁,小编这里做了安装,假诺绑定过账号,就没有供给再一次绑定,第贰遍登录会跳转绑定页面,进步举办绑定。

@Throws(Exception::class)
override fun preHandle(request: HttpServletRequest, response: HttpServletResponse, handler: Any): Boolean {
//从header中得到token
val token = request.getHeader("x-token")
//验证token
val tokenModel = tokenService.checkToken(token)
if (tokenModel != null) {
//尽管token验证成功,将token对应的用户id存在request中,便于之后流入
request.setAttribute("tokenModel", tokenModel)
return true
}
//假若证明token退步,再次来到40一张冠李戴
response.status = HttpServletResponse.SC_UNAUTHORIZED
return false
}
}

2. 获取openid和session_key

async onGotUserInfo {

if (e.detail.errMsg ==='getUserInfo:ok') {

let res =await wepy.login()

if {

wepy.setStorageSync(USER_INFO, e.detail.userInfo)

let systemInfo = wepy.getSystemInfoSync()

wepy.setStorageSync(SYSTEM_INFO, systemInfo)

let rlt =await api.wxJsCode2Session({

query: {

jsCode: res.code,

nickName: e.detail.userInfo.nickName

}

})

if {

let data = rlt.data

console.log(data.code)

console.log

if (data.code ===100) {

await tip.confirm('授权成功,第贰遍登陆请绑定职员和工人号')

wepy.navigateTo({

url:'reg'

})

}

wepy.setStorageSync(TOKEN, data.token)

wepy.setStorageSync(ISSTAFF, 1)

wepy.switchTab({

url:'home'

})

}else {

let res =await wepy.showModal({

title:'appid有误',

content:'授权战败'

})

if (res.confirm) {

wepy.switchTab({

url:'home'

})

}

}

}

}

}

我们先来介绍下openid,用过公众号的童鞋应该对那个标记都不不熟悉了,在万众平台里,用来标志每种用户在订阅号、服务号、小程序那三种分裂应用的唯1标记,也正是说每种用户在各个应用的openid都以区别等的,所以在小程序里,咱们可以用openid来标志用户的唯1性。

绑定页面包车型客车乞请

那么session_key是用来干嘛的呢?有了用户标记,大家就要求让该用户实行登入,那么 session_key 就有限支撑了眼下用户打开对话操作的管用,那些session_key是微信服务端给我们派发的。也正是说,大家得以用这么些标记来直接地维护我们小程序用户的登陆态,那么这几个session_key是怎么获得的吧?我们必要在温馨的服务端请求微信提供的第一方接口 ,那些接口要求带上多个参数字段:

async singin {

if (e.detail.errMsg ==='getUserInfo:ok') {

let res =await wepy.login()

if {

let rlt =await api.singin({

query: {

jsCode: res.code,

nickName: e.detail.userInfo.nickName,

username:this.user_name,

userpass:md5.hex_md5((this.user_pass).toLowerCase

}

})

if {

wepy.setStorageSync(TOKEN, rlt.data.token)

wepy.setStorageSync(ISSTAFF, 1)

let data = rlt.data

console.log(data.code)

await tip.confirm

wepy.switchTab({

url:'home'

})

}

}

}

}

本文由韦德国际1946发布于韦德国际1946国际网址,转载请注明出处:签到鉴权,django开荒微信小程序后端登入和鉴权

关键词: 后端 程序 django weixin