国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
微信掃碼登錄很難嗎?5步幫你搞定

官方文檔:https://developers.weixin.qq.com/doc/oplatform/Website_App/WeChat_Login/Wechat_Login.html

1. 授權(quán)流程說明

微信OAuth2.0授權(quán)登錄讓微信用戶使用微信身份安全登錄第三方應(yīng)用或網(wǎng)站,在微信用戶授權(quán)登錄已接入微信OAuth2.0的第三方應(yīng)用后,第三方可以獲取到用戶的接口調(diào)用憑證(access_token),通過access_token可以進(jìn)行微信開放平臺授權(quán)關(guān)系接口調(diào)用,從而可實現(xiàn)獲取微信用戶基本開放信息和幫助用戶實現(xiàn)基礎(chǔ)開放功能等。

微信OAuth2.0授權(quán)登錄目前支持authorization_code模式,適用于擁有server端的應(yīng)用授權(quán)。該模式整體流程為:

① 第三方發(fā)起微信授權(quán)登錄請求,微信用戶允許授權(quán)第三方應(yīng)用后,微信會拉起應(yīng)用或重定向到第三方網(wǎng)站,并且?guī)鲜跈?quán)臨時票據(jù)code參數(shù);

② 通過code參數(shù)加上AppID和AppSecret等,通過API換取access_token;

③ 通過access_token進(jìn)行接口調(diào)用,獲取用戶基本數(shù)據(jù)資源或幫助用戶實現(xiàn)基本操作。

第一步:請求CODE

第三方使用網(wǎng)站應(yīng)用授權(quán)登錄前請注意已獲取相應(yīng)網(wǎng)頁授權(quán)作用域(scope=snsapi_login),則可以通過在PC端打開以下鏈接:https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect

返回說明

用戶允許授權(quán)后,將會重定向到redirect_uri的網(wǎng)址上,并且?guī)蟘ode和state參數(shù)

redirect_uri?code=CODE&state=STATE

若用戶禁止授權(quán),則重定向后不會帶上code參數(shù),僅會帶上state參數(shù)

redirect_uri?state=STATE

例如:登錄一號店網(wǎng)站應(yīng)用 https://passport.yhd.com/wechat/login.do 打開后,一號店會生成state參數(shù),跳轉(zhuǎn)到 https://open.weixin.qq.com/connect/qrconnect?appid=wxbdc5610cc59c1631&redirect_uri=https%3A%2F%2Fpassport.yhd.com%2Fwechat%2Fcallback.do&response_type=code&scope=snsapi_login&state=3d6be0a4035d839573b04816624a415e#wechat_redirect 微信用戶使用微信掃描二維碼并且確認(rèn)登錄后,PC端會跳轉(zhuǎn)到 https://passport.yhd.com/wechat/callback.do?code=CODE&state=3d6be0a4035d839573b04816624a415e

第二步:通過code獲取access_token

通過code獲取access_token

https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

返回說明

正確的返回:


'access_token':'ACCESS_TOKEN'
'expires_in':7200
'refresh_token':'REFRESH_TOKEN',
'openid':'OPENID'
'scope':'SCOPE',
'unionid''o6_bmasdasdsad6_2sgVt7hMZOPfL'
}

錯誤返回樣例:

{'errcode':40029,'errmsg':'invalid code'}
  • Appsecret 是應(yīng)用接口使用密鑰,泄漏后將可能導(dǎo)致應(yīng)用數(shù)據(jù)泄漏、應(yīng)用的用戶數(shù)據(jù)泄漏等高風(fēng)險后果;存儲在客戶端,極有可能被惡意竊?。ㄈ绶淳幾g獲取Appsecret);

  • access_token 為用戶授權(quán)第三方應(yīng)用發(fā)起接口調(diào)用的憑證(相當(dāng)于用戶登錄態(tài)),存儲在客戶端,可能出現(xiàn)惡意獲取access_token 后導(dǎo)致的用戶數(shù)據(jù)泄漏、用戶微信相關(guān)接口功能被惡意發(fā)起等行為;

  • refresh_token 為用戶授權(quán)第三方應(yīng)用的長效憑證,僅用于刷新access_token,但泄漏后相當(dāng)于access_token 泄漏,風(fēng)險同上。

建議將secret、用戶數(shù)據(jù)(如access_token)放在App云端服務(wù)器,由云端中轉(zhuǎn)接口調(diào)用請求。

第三步:通過access_token調(diào)用接口

獲取access_token后,進(jìn)行接口調(diào)用,有以下前提:

  1. access_token有效且未超時;

  2. 微信用戶已授權(quán)給第三方應(yīng)用賬號相應(yīng)接口作用域(scope)。

對于接口作用域(scope),能調(diào)用的接口有以下:

2. 授權(quán)流程代碼

因為微信開放平臺的AppiD和APPSecret和微信公眾平臺的AppiD和AppSecret都是不同的,因此需要配置一下:

# 開放平臺
wechat.open-app-id=wx6ad144e54af67d87
wechat.open-app-secret=91a2ff6d38a2bbccfb7e9f9079108e2e
@Data
@Component
@ConfigurationProperties(prefix = 'wechat')
public class WechatAccountConfig {

    //公眾號appid
    private String mpAppId;

    //公眾號appSecret
    private String mpAppSecret;

    //商戶號
    private String mchId;

    //商戶秘鑰
    private String mchKey;
    
    //商戶證書路徑
    private String keyPath;

    //微信支付異步通知
    private String notifyUrl;

    //開放平臺id
    private String openAppId;

    //開放平臺秘鑰
    private String openAppSecret;
}
@Configuration
public class WechatOpenConfig {

    @Autowired
    private WechatAccountConfig accountConfig;

    @Bean
    public WxMpService wxOpenService() {
        WxMpService wxOpenService = new WxMpServiceImpl();
        wxOpenService.setWxMpConfigStorage(wxOpenConfigStorage());
        return wxOpenService;
    }

    @Bean
    public WxMpConfigStorage wxOpenConfigStorage() {
        WxMpInMemoryConfigStorage wxMpInMemoryConfigStorage = new WxMpInMemoryConfigStorage();
        wxMpInMemoryConfigStorage.setAppId(accountConfig.getOpenAppId());
        wxMpInMemoryConfigStorage.setSecret(accountConfig.getOpenAppSecret());
        return wxMpInMemoryConfigStorage;
    }
}
@Controller
@RequestMapping('/wechat')
@Slf4j
public class WeChatController {
    @Autowired
    private WxMpService wxMpService;

    @Autowired
    private WxMpService wxOpenService;

    @GetMapping('/qrAuthorize')
    public String qrAuthorize() {
        //returnUrl就是用戶授權(quán)同意后回調(diào)的地址
        String returnUrl = 'http://heng.nat300.top/sell/wechat/qrUserInfo';

        //引導(dǎo)用戶訪問這個鏈接,進(jìn)行授權(quán)
        String url = wxOpenService.buildQrConnectUrl(returnUrl, WxConsts.QRCONNECT_SCOPE_SNSAPI_LOGIN, URLEncoder.encode(returnUrl));
        return 'redirect:' + url;
    }

    //用戶授權(quán)同意后回調(diào)的地址,從請求參數(shù)中獲取code
    @GetMapping('/qrUserInfo')
    public String qrUserInfo(@RequestParam('code') String code) {
        WxMpOAuth2AccessToken wxMpOAuth2AccessToken = new WxMpOAuth2AccessToken();
        try {
            //通過code獲取access_token
            wxMpOAuth2AccessToken = wxOpenService.oauth2getAccessToken(code);
        } catch (WxErrorException e) {
            log.error('【微信網(wǎng)頁授權(quán)】{}', e);
            throw new SellException(ResultEnum.WECHAT_MP_ERROR.getCode(), e.getError().getErrorMsg());
        }
        //從token中獲取openid
        String openId = wxMpOAuth2AccessToken.getOpenId();

        //這個地址可有可無,反正只是為了拿到openid,但是如果沒有會報404錯誤,為了好看隨便返回一個百度的地址
        String  returnUrl = 'http://www.baidu.com';

        log.info('openid={}', openId);

        return 'redirect:' + returnUrl + '?openid='+openId;
    }
}

請求路徑:在瀏覽器打開

https://open.weixin.qq.com/connect/qrconnect?appid=wx6ad144e54af67d87&redirect_uri=http%3A%2F%2Fsell.springboot.cn%2Fsell%2Fqr%2FoTgZpwenC6lwO2eTDDf_-UYyFtqI&response_type=code&scope=snsapi_login&state=http%3a%2f%2fheng.nat300.top%2fsell%2fwechat%2fqrUserInfo

獲取了openid:openid=o9AREv7Xr22ZUk6BtVqw82bb6AFk

3. 用戶登錄和登出

@Controller
@RequestMapping('/seller')
public class SellerUserController {

    @Autowired
    private SellerService sellerService;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private ProjectUrlConfig projectUrlConfig;

    @GetMapping('/login')
    public ModelAndView login(@RequestParam('openid') String openid,                               HttpServletResponse response,                               Map<String, Object> map) {

        //1. openid去和數(shù)據(jù)庫里的數(shù)據(jù)匹配
        SellerInfo sellerInfo = sellerService.findSellerInfoByOpenid(openid);
        if (sellerInfo == null) {
            map.put('msg', ResultEnum.LOGIN_FAIL.getMessage());
            map.put('url''/sell/seller/order/list');
            return new ModelAndView('common/error');
        }

        //2. 設(shè)置token至redis
        String token = UUID.randomUUID().toString();
        //設(shè)置token的過期時間
        Integer expire = RedisConstant.EXPIRE;

        redisTemplate.opsForValue().set(String.format(RedisConstant.TOKEN_PREFIX, token), openid, expire, TimeUnit.SECONDS);

        //3. 設(shè)置token至cookie
        CookieUtil.set(response, CookieConstant.TOKEN, token, expire);

        return new ModelAndView('redirect:' + 'http://heng.nat300.top/sell/seller/order/list');
    }

    @GetMapping('/logout')
    public ModelAndView logout(HttpServletRequest request,                        HttpServletResponse response,                        Map<String, Object> map) {
        //1. 從cookie里查詢
        Cookie cookie = CookieUtil.get(request, CookieConstant.TOKEN);
        if (cookie != null) {
            //2. 清除redis
            redisTemplate.opsForValue().getOperations().delete(String.format(RedisConstant.TOKEN_PREFIX, cookie.getValue()));

            //3. 清除cookie
            CookieUtil.set(response, CookieConstant.TOKEN, null0);
        }

        map.put('msg', ResultEnum.LOGOUT_SUCCESS.getMessage());
        map.put('url''/sell/seller/order/list');
        return new ModelAndView('common/success', map);
    }
}

① 將上一步獲取到的openid存入數(shù)據(jù)庫

② 將授權(quán)后跳轉(zhuǎn)的地址改為登錄地址

 //用戶授權(quán)同意后回調(diào)的地址,從請求參數(shù)中獲取code
    @GetMapping('/qrUserInfo')
    public String qrUserInfo(@RequestParam('code') String code) {
        WxMpOAuth2AccessToken wxMpOAuth2AccessToken = new WxMpOAuth2AccessToken();
        try {
            //通過code獲取access_token
            wxMpOAuth2AccessToken = wxOpenService.oauth2getAccessToken(code);
        } catch (WxErrorException e) {
            log.error('【微信網(wǎng)頁授權(quán)】{}', e);
            throw new SellException(ResultEnum.WECHAT_MP_ERROR.getCode(), e.getError().getErrorMsg());
        }
        //從token中獲取openid
        String openId = wxMpOAuth2AccessToken.getOpenId();

        //授權(quán)成功后跳轉(zhuǎn)到賣家系統(tǒng)的登錄地址
        String  returnUrl = 'http://heng.nat300.top/sell/seller/login';

        log.info('openid={}', openId);

        return 'redirect:' + returnUrl + '?openid='+openId;
    }

③ 在瀏覽器請求這個鏈接:https://open.weixin.qq.com/connect/qrconnect?appid=wx6ad144e54af67d87&redirect_uri=http%3A%2F%2Fsell.springboot.cn%2Fsell%2Fqr%2FoTgZpwenC6lwO2eTDDf_-UYyFtqI&response_type=code&scope=snsapi_login&state=http%3a%2f%2fheng.nat300.top%2fsell%2fwechat%2fqrUserInfo

第三應(yīng)用請求使用微信掃碼登錄,而不是使用本網(wǎng)站的密碼:

用戶同意授權(quán)后登入第三方應(yīng)用的后臺管理系統(tǒng):

4. Spring AOP校驗用戶有沒有登錄

@Aspect
@Component
@Slf4j
public class SellerAuthorizeAspect {

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Pointcut('execution(public * com.hh.controller.Seller*.*(..))' +
    '&& !execution(public * com.hh.controller.SellerUserController.*(..))')

    public void verify() {}

    @Before('verify()')
    public void doVerify() {
        
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        //查詢cookie
        Cookie cookie = CookieUtil.get(request, CookieConstant.TOKEN);
        //如果cookie中沒有token說明已經(jīng)登出或者根本沒有登錄
        if (cookie == null) {
            log.warn('【登錄校驗】Cookie中查不到token');
            //校驗不通過,拋出異常
            throw new SellerAuthorizeException();
        }

        //去redis里查詢
        String tokenValue = redisTemplate.opsForValue().get(String.format(RedisConstant.TOKEN_PREFIX, cookie.getValue()));
        //如果redis中沒有對應(yīng)的openid,同樣表示登出或者根本沒有登錄
        if (StringUtils.isEmpty(tokenValue)) {
            log.warn('【登錄校驗】Redis中查不到token');
            throw new SellerAuthorizeException();
        }
    }
}

5. 攔截登錄校驗不通過拋出的異常

攔截及登錄校驗不通過的異常,讓其跳轉(zhuǎn)到登錄頁面,掃碼登錄

@ControllerAdvice
public class SellExceptionHandler {
    //攔截登錄異常
    @ExceptionHandler(value = SellerAuthorizeException.class)     public ModelAndView handlerAuthorizeException() {
        //攔截異常后,跳轉(zhuǎn)到登錄界面
        return new ModelAndView('redirect:'.concat('https://open.weixin.qq.com/connect/qrconnect?' +
                'appid=wx6ad144e54af67d87' +
                '&redirect_uri=http%3A%2F%2Fsell.springboot.cn%2Fsell%2Fqr%2F' +
                'oTgZpwenC6lwO2eTDDf_-UYyFtqI' +
                '&response_type=code&scope=snsapi_login' +
                '&state=http%3a%2f%2fheng.nat300.top%2fsell%2fwechat%2fqrUserInfo'));
    }
    @ExceptionHandler(value = SellException.class)     @ResponseBody     public ResultVO handlerSellerException(SellException e) {
        return ResultVOUtil.error(e.getCode(), e.getMessage());
    }
    @ExceptionHandler(value = ResponseBankException.class)     @ResponseStatus(HttpStatus.FORBIDDEN)     public void handleResponseBankException() {
    }
}

來源:hengheng.blog.csdn.net/article/details/107823201 ###

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
OAuth2.0實戰(zhàn)1(分析簡書的微信登陸及實現(xiàn))
使用Golang開發(fā)微信公眾平臺
C#開發(fā)微信門戶及應(yīng)用(4)
Django微信公眾號開發(fā)(一)公眾號內(nèi)網(wǎng)頁授權(quán)登錄后微信獲取用戶信息
微信公眾號支付功能開發(fā)
微信公眾平臺開發(fā)
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服