node.js - 通过 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}`);
有什么我遗漏或做错了什么,请告诉我。
解决方案
通过在我获得 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);
}
推荐阅读
- mysql - 计数函数只返回一行,但只显示一个客户的前 5 个航班号的计数。这里有什么问题?
- javascript - 需要优化代码来检查以下 json 转换的几个条件
- sql - 想从两个不同的表中减去两个日期,出现语法错误
- .net - 在项目引用链中,输出中缺少引用的 dll
- ios - iOS 上的 Xamarin.Forms:出现软键盘时缩小页面高度而不是向上移动
- python - Pytorch 相当于“tf.reverse_sequence”?
- django - 无法使用 Django 发送电子邮件
- swift - 如何更改文本视图中某些文本的颜色?
- php - 从 laravel 到 API 的 JSON 卷曲
- c# - 是否有模型验证属性可以在不使用自定义代码的情况下检查参数类型?