天貓精靈對接1:outh對接


公司的智能家居產品需要接入語音控制,目前在對接阿里語音的天貓精靈

 

對接天貓精靈的第一步是完成outh鑒權

https://doc-bot.tmall.com/docs/doc.htm?spm=0.7629140.0.0.84a01780RQrNoT&treeId=393&articleId=106999&docType=1

 

鑒權的博客可以參照如下博客

 

1.Java實現Aligenie天貓精靈OAuth2.0認證授權流程

https://blog.csdn.net/willianfu/article/details/87464528

免登錄式的

 

https://blog.csdn.net/weixin_41581158/article/details/81120028

帶有登錄的

 

貼個代碼說說自己的實現

天貓精靈的文檔還是很詳細的,第一步是登錄認證,認證OK之后重定向天貓精靈的地址(帶上code的)

登錄過程還是必要的,例如我的登錄過程,登錄上報了單元房ID,這樣就把這個天貓精靈和房屋建立關系了,通過這個code賦值的token也是單元房ID,這樣在設備控制和查詢的時候通過token就知道是查詢哪個單元房的設備了

 

第一步登錄,將回調地址放入map中,等待登錄成功后回調地址+code信息重定向

@RequestMapping(value = "/login")
    public String login(@ModelAttribute LoginForm loginForm, HttpServletRequest request) {
        String unicede = IdUtil.getId() + "";

        String repsonse = "login";
        try {
            //構建OAuth 授權請求
            OAuthAuthzRequest oauthRequest = new OAuthAuthzRequest(request);

            //if (oauthRequest.getClientId() != null && oauthRequest.getClientId().equals(clientId)) {
            LOG.info("clientID:" + oauthRequest.getClientId());
            //利用oauth授權請求設置responseType,目前僅支持CODE,另外還有TOKEN
            String responseType = oauthRequest.getParam(OAuth.OAUTH_RESPONSE_TYPE);
            //進行OAuth響應構建
            OAuthASResponse.OAuthAuthorizationResponseBuilder builder =
                    OAuthASResponse.authorizationResponse(request, HttpServletResponse.SC_FOUND);
            builder.setParam("state", oauthRequest.getState());
            //得到到客戶端重定向地址
            String redirectURI = oauthRequest.getParam(OAuth.OAUTH_REDIRECT_URI);
            //構建響應
            OAuthResponse response = builder.location(redirectURI).buildQueryMessage();
            String responceUri = response.getLocationUri();

            //將url放入map,待用戶登錄后填上code做回調
            loginForm.setUnicode(unicede);
            map.put(unicede, responceUri);
            //}

        } catch (OAuthSystemException e) {
            LOG.error("處理獲取code請求時發生異常", e);
            repsonse = "error";
        } catch (OAuthProblemException e) {
            LOG.error("處理獲取code請求時發生異常", e);
            repsonse = "error";
        }
        return repsonse;

    }

 

第二部登錄鑒權,登錄成功重定向至天貓精靈服務器,即返回天貓精靈code

@RequestMapping(value = "/loginSucess")
    public String add(@ModelAttribute LoginForm loginForm) {
        String uniCode = loginForm.getUnicode();
        String redirectURL = map.get(uniCode);
        if (redirectURL == null) {
            LOG.error("用戶回調url為null,需要重新登錄");
            return "error";
        }
        map.remove(uniCode);

        //houseID鑒權
        String house = loginForm.getHouseId();

        IotGwInfo iotGwInfo = new IotGwInfo();
        iotGwInfo.setIhouseId(house);
        List<IotGwInfo> iotGwInfoList = iotGwInfoService.getIotGwInfos(iotGwInfo);
        if (iotGwInfoList == null || iotGwInfoList.isEmpty()) {
            LOG.error("上報的houseid:{}下找不到網關", house);
            return "error";
        }

        redirectURL = redirectURL + "&code=" + loginForm.getHouseId();

        LOG.info("登錄回調地址:" + redirectURL);
        return "redirect:" + redirectURL;
    }

 

第三部 返回token,我的代碼里token值=代碼值=單元房ID,因為服務器做的是支持多網關的,一個單元房可以有多個網關

 @RequestMapping(value = "/accessToken", method = RequestMethod.POST)
    public HttpEntity token(HttpServletRequest request) throws OAuthSystemException {
        OAuthResponse response = null;
        //構建OAuth請求
        try {
            OAuthTokenRequest oauthRequest = new OAuthTokenRequest(request);

            String id = oauthRequest.getClientSecret();
            LOG.info("clientID:" + id);
            //if (id != null && id.equals(clientId)) {
            String token = request.getParameter("code");
            //生成OAuth響應
            response = OAuthASResponse
                    .tokenResponse(HttpServletResponse.SC_OK)
                    .setAccessToken(token)
                    .setRefreshToken(token)
                    .setParam("expires_in", EXPIRE_TIME)
                    .buildJSONMessage();
            //}
            //根據OAuthResponse生成ResponseEntity
            return new ResponseEntity(response.getBody(), HttpStatus.valueOf(response.getResponseStatus()));

        } catch (OAuthSystemException e) {
            LOG.error("獲取accessToken發生問題", e);
            response = OAuthASResponse
                    .tokenResponse(HttpServletResponse.SC_OK)
                    .setParam("error", "101")
                    .setParam("error_description", "內部錯誤")
                    .buildJSONMessage();
            return new ResponseEntity(response.getBody(), HttpStatus.valueOf(response.getResponseStatus()));
        } catch (OAuthProblemException e) {
            LOG.error("獲取accessToken發生問題", e);
            response = OAuthASResponse
                    .tokenResponse(HttpServletResponse.SC_OK)
                    .setParam("error", "102")
                    .setParam("error_description", "參數錯誤")
                    .buildJSONMessage();

            return new ResponseEntity(response.getBody(), HttpStatus.valueOf(response.getResponseStatus()));
        }

    }

 

設備操作這塊就是json的了,主要是設備發現,設備查詢,設備控制三種功能。

@ApiOperation(value = "設備接口", notes = "設備接口")
    @RequestMapping(value = "/deviceHandle", method = RequestMethod.POST)
    public AliDevice deviceHandle(@RequestBody AliDevice aliDeviceReq) {
        LOG.info("請求數據:" + JSON.toJSONString(aliDeviceReq));

        String action = aliDeviceReq.getHeader().getNamespace();
        AliDevice resp = new AliDevice();
        resp.setHeader(aliDeviceReq.getHeader());
        switch (action) {
            case Constants.Namespace.deviceDiscovery: {
                aliboxDeviceService.deviceDiscovery(aliDeviceReq.getPayload().getAccessToken(), resp);
                resp.getHeader().setName(Constants.Name.deviceDiscoveryResp);
                break;
            }
            case Constants.Namespace.deviceControl: {

                aliboxDeviceService.deviceControl(aliDeviceReq, resp);
                break;
            }
            case Constants.Namespace.deviceQuery: {
                break;
            }
            default: {

            }
        }

        LOG.info("返回數據:" + JSON.toJSONString(resp));
        return resp;
    }

 

以上是天貓精靈對接

在后台服務器里還需要一個天貓精靈的登錄頁面,就直接寫在后台了,使用thymeleaf,這塊就是學習做了,因為對前段不輸,就是白板寫出了功能。

 

spring:
  profiles: shypro
  thymeleaf:
    prefix: classpath:/templates/
    suffix: .html
    mode: LEGACYHTML5
    encoding: UTF-8
    content-type: text/html
    cache: false
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8"></meta>
    <title>login</title>
</head>
<body>
<h1>login</h1>
<div th:object="${loginForm}">
    <p th:text="*{houseId}"></p>
    <p th:text="*{unicode}"></p>
</div>
<form action="#" th:action="@{/alibox/loginSucess}" th:object="${loginForm}" method="post">
    <input type="text" th:field="*{houseId}"/>
    <input type="text" th:field="*{unicode}" text="${loginForm.unicode}"/>
    <input type="submit"/>
</form>
</body>
</html>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM