NextJS -将用户发送到自定义url并处理来自第三方应用程序的响应



我正在构建一个应用程序,将客户发送到一个URL,该URL要求用户打开一个应用程序(URL以zel开头),然后应用程序将发送请求到我的服务器。我想实现以下旅程:

  1. 用户点击登录按钮。
  2. 要求用户打开应用程序并完成登录。
  3. 应用程序使用回调发送消息到我的服务器,说客户完成登录。
  4. 我验证用户已经登录,然后将他们重定向到一个新的路径(例如:/afterlogin)

我不知道如何做到这一点。你能帮我吗?

我有以下代码:

// pages/login.js
import axios from 'axios';
import { useRouter } from 'next/router';
export default function Login() {
const router = useRouter();
const handleClick = () => {
axios.get('https://api.runonflux.io/id/loginphrase').then(response => {
if (response.data.status === 'success') {
var loginPhrase = response.data.data;
if (loginPhrase) {
router.push(`zel:?action=sign&message=${loginPhrase}&callback=${process.env.DOMAIN}api/validateSignature`);
}
}
});
}
return (
<div>
<button onClick={handleClick}>Login</button>
</div>
)
}

这是登录页面,用户将点击登录按钮,向API请求获取短语,然后用户将被重定向到打开应用程序并签署消息。

// pages/api/validateSignature.js
export default function handler(req, res) {
if (req.method == 'GET') {
}
var url = "https://api.runonflux.io/id/verifylogin";
var axios = require('axios');
var data = JSON.stringify({
"loginPhrase": req.body.message,
"signature": req.body.signature,
"zelid": req.body.address
});
var config = {
method: 'post',
url: url,
data: data
};
axios(config)
.then(function (response) {
console.log(response.data);
})
.catch(function (error) {
console.log(error);
});
res.status(200).json({ name: 'John Doe' })
}

这将处理应用程序回调。

我还制作了一个演示流程的视频- https://i.stack.imgur.com/Fn4j5.jpg

我最终做的是实现MongoDB来帮助我解决这个问题。

我正在将用户重定向到等待页面,该页面每3秒检查MongoDB,以查看客户是否完成登录:

// pages/waiting/[loginPhrase.js]
import React, { useState, useEffect } from 'react';
import { useRouter } from 'next/router'
const WaitingPage = () => {
const router = useRouter();
const { loginPhrase } = router.query
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
const checkApi = async () => {
try {
const response = await fetch('/api/checkMessage', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ "loginPhrase": loginPhrase }),
});
const json = await response.json();
console.log(json.data[0]);
if (json.data[0] !== undefined) {
const responseVerify = await fetch('https://api.runonflux.io/id/verifylogin', {
method: 'POST',
body: JSON.stringify({ "address": json.data[0].address, "message": json.data[0].message, "signature": json.data[0].signature }),
});
const respJson = await responseVerify.json();
console.log(respJson);
if (respJson.status === 'success' && respJson.data.message == 'Successfully logged in') {
router.push(`/success`);
}
}
} catch (err) {
setLoading(false);
console.error(err);
}
};
const intervalId = setInterval(checkApi, 3000);
return () => clearInterval(intervalId);
}, []);

return (
<div>
{loading ? (
<p>Loading...</p>
) : data ? (
<p>Data received: {JSON.stringify(data)}</p>
) : (
<p>No data received</p>
)}
</div>
);
};
export default WaitingPage;

我实现了两个api调用-一个用于应用程序回调,它将数据写入MongoDB:

// pages/api/signedMessage.js
import clientPromise from "../../lib/mongodb";
export default async function handler(req, res) {
const client = await clientPromise;
const db = client.db("zel_login");
if (req.method === "POST") {
if (!req.body.address || !req.body.message || !req.body.signature) {
return res.status(400).json({ status: 400, message: "Bad Request" })
}
let messageObject = {
createdAt: new Date(new Date().toISOString()),
address: req.body.address,
message: req.body.message,
signature: req.body.signature
}
let newMessage = await db.collection("signed_messages").insertOne(messageObject);
res.json(newMessage);
}
}

另一个将尝试找到loginPhrase,然后用一个额外的API调用验证它:

// pages/api/checkMessage.js
import clientPromise from "../../lib/mongodb";
export default async function handler(req, res) {
const client = await clientPromise;
const db = client.db("zel_login");
if (req.method === "POST") {
const message = await db.collection("signed_messages").find({ "message": req.body.loginPhrase }).toArray();
res.json({ status: 200, data: message });
}
}

最新更新