zoukankan      html  css  js  c++  java
  • 天猫精灵对接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>
  • 相关阅读:
    前端必须掌握的 docker 技能(2)
    前端必须掌握的 docker 技能(1)
    异步 map 和模块打包
    import 和组件库按需引入
    babel-node 和 nodemon
    linux和mac 终端代理
    yarn.lock 是干什么的
    pwa 总结
    设计模式(5): vue 不监听绑定的变量
    django+celery+redis应用
  • 原文地址:https://www.cnblogs.com/heroinss/p/10442945.html
Copyright © 2011-2022 走看看