首页 > 解决方案 > 通过 CIVIC Symfony+Reactjs+NodeJs 登录

问题描述

我有一个基于 Symfony 4 的项目,我正在使用 React.js 通过CIVIC登录我正在关注此链接,但面临 401 未经授权的错误。我对文档有点困惑。我是 React 和 Nodejs 的新手。我搜索了解决方案并找到了这个链接如何交换用户数据?. 也按照此链接中的描述进行了尝试,但无法对其进行排序。

当我通过 CIVIC 按钮单击登录时,此 api 命中https://api.civic.com/sip/prod/scopeRequest/qrcode并返回401 unauthorized

我的反应组件

        import React from 'react';
        var civicSip;
        function sendAuthCode(token) {
            // axios.defaults.headers.common['Authorization'] = `Civic ${token}`;
            axios.post('mydomain:8080/api/authenticate', { token })
                .then(({ data }) => {
                    console.log('===');
                    console.log(data);
                }).catch((error) => {
                console.log(error);
            });
        }
        const CivicLoginButton = () => {
            civicSip = new civic.sip({ appId: 'My-AppId' });
            civicSip.on('auth-code-received', function (event) {
                // encoded JWT Token is sent to the server
                const jwtToken = event.response;
                // Your function to pass JWT token to your server
                sendAuthCode(jwtToken);
                console.log('jwt', event)
            });
            civicSip.on('user-cancelled', function (event) {
                    event:
                    {
                       "scoperequest:user-cancelled"
                    }
            });
            civicSip.on('read', function (event) {
                /*
                    event:
                    {
                      event: "scoperequest:read"
                    }
                */
            });

            // Error events.
            civicSip.on('civic-sip-error', function (error) {
                // handle error display if necessary.
                console.log('   Error type = ' + error.type);
                console.log('   Error message = ' + error.message);
            });
            return (
                    <a href="#"
                       onClick={() => {
                           civicSip.signup({ style: 'popup', scopeRequest: civicSip.ScopeRequests.BASIC_SIGNUP })
                    }}
                   className="btn"><span>Sign in with Civic</span></a>
            );
        };
        export default CivicLoginButton;

节点

        'use strict';
        const express = require('express');
        const cors = require('cors');
        const app = express();
        const bodyParser = require('body-parser');
        const civicSip = require('civic-sip-api');
        const https = require('https');
        const fs = require('fs');
        const path = require('path');
        const router = express.Router();

        app.use(cors());
        app.use(bodyParser.urlencoded({ extended: true }));
        app.use(bodyParser.json());

        const port = process.env.PORT || 8080;

        const civicClient = civicSip.newClient({
            appId: 'My-AppId',
            appSecret: 'My-AppSecret',
            prvKey: 'My-AppPrvKey', // Here I tried Private sigining key and private encryption key as well
        });

        router.get('/sign-in', (req, res) => {
            res.sendFile(path.join(__dirname + '/pages/signin.html.twig'));
        });

        router.route('/api/authenticate')
            .post((req, res) => {
                const { token } = req.body;

                console.log(token);

                civicClient.exchangeCode(token)
                    .then((userData) => {
                        console.log(`userData: ${JSON.stringify(userData, null, 4)}`);
                        res.json(userData);
                    }).catch((error) => {
                    console.log('error', error);
                    res.send(error, 500);
                });
            });

        app.use('/sign-in', router);
        app.listen(port);
        console.log(`Running node server on port ${port}`);

有什么我遗漏或做错了什么,请告诉我。

标签: node.jsreactjs

解决方案


通过在我获得 API 凭据的 CIVIC 集成面板中添加白名单域来解决此问题。在此处输入图像描述

还与 Symfony 合作,将这个php api 客户端用于服务器端而不是 Nodejs

Symfony 控制器

           public function signInViaCIVIC(Request $request)
        {
            $return = array();
            $em = $this->getDoctrine()->getManager();
            $data = json_decode(
                $request->getContent(),
                true
            );
            // Configure Civic App credentials.
            $config = new AppConfig(
                'My-AppId',
                'My-AppSecret',
                'My-AppPrivateSigningKey'
            );

    // Instantiate Civic API client with config and HTTP client.
            $sipClient = new Client($config, new \GuzzleHttp\Client());
            if (!empty($data['token'])) {
    // Exchange Civic authorization code for requested user data.
                $userData = $sipClient->exchangeToken($data['token']);

                $userId = $userData->userId();
                $email = $userData->getByLabel('contact.personal.email')->value();
                $phone = $userData->getByLabel('contact.personal.phoneNumber')->value();
                $param = array('email' => $email);
                $FrontUserRepository = $em->getRepository(FrontUser::class);
                $FrontUser = $FrontUserRepository->findOneBy($param);
                if (empty($FrontUser)) {
                    $FrontUserNew = new FrontUser();
                    $FrontUserNew->setCivicUserId($userId);
                    $FrontUserNew->setEmail($email);
                    $FrontUserNew->setPhoneNumber($phone);
                    $FrontUserNew->setEnabled(1);
                    $FrontUserNew->setCreatedAt(new \DateTime());
                    $em->persist($FrontUserNew);
                    $return['status'] = true;
                } else {
                    $FrontUser->setCivicUserId($userId);
                    $FrontUser->setPhoneNumber($phone);
                    $FrontUser->setEnabled(1);
                    $FrontUser->setUpdatedAt(new \DateTime());
                    $return['status'] = true;
                }
                $em->flush();
                $session = new Session();
    //            $session->start();
    // set and get session attributes
                $session->set('userCivicUserId', $userId);
                $session->set('userEmail', $email);
                $session->set('userPhoneNumber', $phone);
            }
            return new JsonResponse($return);
        }

推荐阅读