[英]How to process data before sending to server in next js environment?
I'm currently making some web site which need authentication.我目前正在制作一些需要身份验证的 web 站点。 I use Next(React) and typescript for web dev.我将 Next(React) 和 typescript 用于 web 开发。
My goal is to make most of pages as ServerSideRendered or StaticHTML.我的目标是将大部分页面设置为 ServerSideRendered 或 StaticHTML。 But I faced problem at the very beginning of development.但是我在开发的一开始就遇到了问题。
I'm currently making login page and overall work flow is below.我目前正在制作登录页面,整体工作流程如下。
The problem I faced with is on 3
-- encrypt before fetch.我面临的问题是3
- 在获取之前加密。 Since it is server side rendered and I didn't put any of react CSR code.因为它是服务器端渲染的,我没有放任何反应 CSR 代码。 It should be encrypted with certain ways.它应该以某些方式加密。 And I ends up with use external script using script tag --put some js files into /public/script/
then import it and run it from browser.最后我使用脚本标签使用外部脚本——将一些 js 文件放入/public/script/
然后导入它并从浏览器运行它。
import React, { Component } from 'react';
import Head from 'next/head';
import { GetServerSideProps, GetServerSidePropsContext, GetServerSidePropsResult } from 'next';
import { RSAHash } from '../../types/alias'; // RSAHash euquivalent with dtype 'string' just alias
import rsa from '../../lib/server-rsa'; // Server-side RSA encryption module
interface LogInProps {
encryptKey: RSAHash
}
export default class LogIn extends Component<LogInProps> {
render() {
return (
<>
<Head>
<script type='module' src='/script/user/submitLoginForm.js' async={false}></script>
</Head>
<form>
<input id='encryptKey' type='hidden' defaultValue={this.props.encryptKey}/> {/* RSA public key */}
<label>Email Address :
<input id='email' type='email'/>
</label>
<label>Password :
<input id='password' type='password'/>
</label>
<button type='submit'>Login</button> {/* !!HERE!! */}
</form>
</>
);
}
}
export const getServerSideProps: GetServerSideProps = async (ctx: GetServerSidePropsContext): Promise<GetServerSidePropsResult<LogInProps>> => {
// Put RSA public key to props for encryption on browser
return {
props: {
encryptKey: rsa.getPublicKey(),
},
};
}
import OpenCrypto from "../library/opencrypto.js";
function submitLoginForm() {
const email = document.getElementById('email').value;
const password = document.getElementById('password').value;
const key = document.getElementById('encryptKey').textContent;
const crypt = new OpenCrypto();
const emailCipher = crypt.rsaEncrypt(credit, email);
const passwordCipher = crypt.rsaEncrypt(credit, sha256(password));
// Also there are function sha256(_) which encrypt to sha256 hash -- not implemented yet-- it is implemented like opencrypto did
console.log(`Receive data ${email} / ${password}`);
console.log(`Got cipher`)
console.log(emailCipher);
console.log(passwordCipher);
// Send POST request for login, then receive session. then proceed with web site maybe?
}
// Some external lightweight RSA encryption library
What I want to know is how can I make browser run function submitLoginForm()
in tag.我想知道的是如何让浏览器在标签中运行 function submitLoginForm()
。
I think I can run it by adding onSubmit="submitLoginForm()"
to submit
type input
.我想我可以通过添加onSubmit="submitLoginForm()"
来submit
类型input
来运行它。 (Position I marked as '!!HERE!!') But it is typescript and it deny to accept string
as prop of onSubmit
. (我标记为 '!!HERE!!' 的位置)但它是 typescript 并且它拒绝接受string
作为onSubmit
的道具。 It shows error Type 'string' is not assignable to type '((event: FormEvent<HTMLButtonElement>) => void) | undefined'.
它显示错误Type 'string' is not assignable to type '((event: FormEvent<HTMLButtonElement>) => void) | undefined'.
Type 'string' is not assignable to type '((event: FormEvent<HTMLButtonElement>) => void) | undefined'.
. .
First, Is this right way to run script?首先,这是运行脚本的正确方法吗? Second, If so, how can I put run
command in that HTML?其次,如果是这样,我该如何在 HTML 中输入run
命令? Third, Ultimately, is it right approach for the feature?第三,归根结底,该功能是否正确? I try to avoid using libraries like next-auth and so on... (But I'm gonna use JWTToken for session)我尽量避免使用诸如 next-auth 之类的库......(但我将使用 JWTToken 进行会话)
Least of codes can be wrong since I'm quite new to Web Dev.因为我对 Web Dev 还很陌生,所以最少的代码可能是错误的。 Appreciate if check that too.欣赏是否也检查。
Thank you.谢谢你。
Appendix.附录。 I tested rendered page with inspector and checked below.我用检查器测试了渲染页面并在下面检查。
getServerSideProps
-- means RSA pub token is inserted well.使用getServerSideProps
可以很好地呈现登录页面——这意味着 RSA pub 令牌插入得很好。crypto
library is received well with status 200 and I can see the code from browser.检查网络面板时,我可以看到外部脚本,它的crypto
库以状态 200 接收良好,我可以从浏览器中看到代码。 I think you should read through the React docs some more time, because it seems like you haven't fully grasped the concepts.我认为您应该多花点时间阅读React文档,因为您似乎还没有完全掌握这些概念。 You can save the values of the input fields in the state.您可以将输入字段的值保存在 state 中。 See here how forms work in React .在这里查看 forms 如何在React中工作。 No need for document.getElementById
, also you can execute your function directly in the component:不需要document.getElementById
,你也可以直接在组件中执行你的 function :
export default class LogIn extends Component<LogInProps> {
state = {
email: "",
password: ""
};
submitLoginForm(e) {
e.preventDefault();
const { email, password } = this.state;
const crypt = new OpenCrypto();
const emailCipher = crypt.rsaEncrypt(credit, email);
const passwordCipher = crypt.rsaEncrypt(credit, sha256(password));
// Send POST request for login, then receive session. then proceed with web site maybe?
}
handleChange(e) {
const name = e.target.name;
const value = e.target.value;
this.setState({ [name]: value });
}
render() {
return (
<>
<Head>
<script type="module" src="/script/user/submitLoginForm.js" async={false}></script>
</Head>
<form onSubmit={this.submitLoginForm}>
<input id="encryptKey" type="hidden" defaultValue={this.props.encryptKey} />{" "}
{/* RSA public key */}
<label>
Email Address :
<input
name="email"
type="email"
value={this.state.email}
onChange={this.handleChange}
/>
</label>
<label>
Password :
<input
name="password"
type="password"
value={this.state.password}
onChange={this.handleChange}
/>
</label>
<button type="submit">Login</button> {/* !!HERE!! */}
</form>
</>
);
}
}
All you would have to do now is use fetch or axios to send your data to the server.您现在要做的就是使用fetch或axios将您的数据发送到服务器。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.