[英]How to process data before sending to server in next js environment?
我目前正在制作一些需要身份验证的 web 站点。 我将 Next(React) 和 typescript 用于 web 开发。
我的目标是将大部分页面设置为 ServerSideRendered 或 StaticHTML。 但是我在开发的一开始就遇到了问题。
我目前正在制作登录页面,整体工作流程如下。
我面临的问题是3
- 在获取之前加密。 因为它是服务器端渲染的,我没有放任何反应 CSR 代码。 它应该以某些方式加密。 最后我使用脚本标签使用外部脚本——将一些 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
我想知道的是如何让浏览器在标签中运行 function submitLoginForm()
。
我想我可以通过添加onSubmit="submitLoginForm()"
来submit
类型input
来运行它。 (我标记为 '!!HERE!!' 的位置)但它是 typescript 并且它拒绝接受string
作为onSubmit
的道具。 它显示错误Type 'string' is not assignable to type '((event: FormEvent<HTMLButtonElement>) => void) | undefined'.
Type 'string' is not assignable to type '((event: FormEvent<HTMLButtonElement>) => void) | undefined'.
.
首先,这是运行脚本的正确方法吗? 其次,如果是这样,我该如何在 HTML 中输入run
命令? 第三,归根结底,该功能是否正确? 我尽量避免使用诸如 next-auth 之类的库......(但我将使用 JWTToken 进行会话)
因为我对 Web Dev 还很陌生,所以最少的代码可能是错误的。 欣赏是否也检查。
谢谢你。
附录。 我用检查器测试了渲染页面并在下面检查。
getServerSideProps
可以很好地呈现登录页面——这意味着 RSA pub 令牌插入得很好。crypto
库以状态 200 接收良好,我可以从浏览器中看到代码。 我认为您应该多花点时间阅读React文档,因为您似乎还没有完全掌握这些概念。 您可以将输入字段的值保存在 state 中。 在这里查看 forms 如何在React中工作。 不需要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>
</>
);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.