nextjs登录的插件很多,官方也提供了很多好几种解决方案和示例代码。
这里我们通过cookie来实现。
一、pages下新增2个文件。
login.js //登录
user.js //登录之后才可以,未登录跳转到login
二、login.js新增用户登录的代码:
安装下antd, axios, nookies
import React, { useState } from 'react'
import {useRouter} from 'next/router'
import { Form, Input, Button, Checkbox, Spin, message } from 'antd';
import axios from 'axios'
import nookies, { setCookie } from 'nookies'
import {encrypt, cookie_name} from '../libs/encrypt'
import Head from 'next/head'
import styles from '../styles/Home.module.css'
const layout = {
labelCol: {
span: 8,
},
wrapperCol: {
span: 16,
},
};
const tailLayout = {
wrapperCol: {
offset: 8,
span: 16,
},
};
export default function Login() {
const router = useRouter()
const [loading, setLoading] = useState(false)
const onFinish = (values) => {
console.log('Success:', values);
setLoading(true)
axios({
url:'https://you_api_auth/auth/',
method:'post',
data:values
}).then(res=>{
let hashkeys = encrypt(res.data);
setCookie(null, cookie_name, hashkeys, {
// maxAge: 30 * 24 * 60 * 60,
maxAge: 3 *24 * 60 * 60, //三天
path: '/',
})
message.success('登录成功!')
setTimeout(()=>{
router.push('/user')
}, 1500)
}).catch(e=>{
console.log(e)
})
};
const onFinishFailed = (errorInfo) => {
console.log('Failed:', errorInfo);
};
return (
<div className={styles.container}>
<Head>
<title>Login</title>
<link rel="icon" href="/favicon.ico" />
</Head>
<Spin spinning={loading}>
<main className={styles.main}>
<Form
{...layout}
name="basic"
initialValues={{
remember: true,
}}
onFinish={onFinish}
onFinishFailed={onFinishFailed}
>
<Form.Item
label="Username"
name="username"
rules={[
{
required: true,
message: 'Please input your username!',
},
]}
>
<Input />
</Form.Item>
<Form.Item
label="Password"
name="password"
rules={[
{
required: true,
message: 'Please input your password!',
},
]}
>
<Input.Password />
</Form.Item>
<Form.Item {...tailLayout} name="remember" valuePropName="checked">
<Checkbox>Remember me</Checkbox>
</Form.Item>
<Form.Item {...tailLayout}>
<Button type="primary" htmlType="submit">
Submit
</Button>
</Form.Item>
</Form>
</main>
</Spin>
<footer className={styles.footer}>
<a
href="https://vercel.com?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
Powered by{' '}
<img src="/vercel.svg" alt="Vercel Logo" className={styles.logo} />
</a>
</footer>
</div>
)
}
export async function getServerSideProps(ctx) {
const cookies = nookies.get(ctx)
//login页面,如果登录了包含了cookie内容,就跳转到登录页面
if(cookies[cookie_name]){
return {
redirect: {
destination: '/user',
permanent: false,
},
}
}
return { props:{} }
}
encrypt.js 代码:
import CryptoJS from 'crypto-js'
const my_secret_string = 'dsds%$54sjdjssd2323232k232!23sdjk@'
const cookie_name = `your_cookie_name`
const encrypt = (string)=> {
if(typeof string === 'string'){
return CryptoJS.AES.encrypt(string, my_secret_string).toString();
}else{
return CryptoJS.AES.encrypt(JSON.stringify(string), my_secret_string).toString();
}
}
const decrypt =(hashkeys)=> {
let bytes = CryptoJS.AES.decrypt(hashkeys, my_secret_string);
let res = bytes.toString(CryptoJS.enc.Utf8);
return JSON.parse(res)?JSON.parse(res):res
}
export {
encrypt,
decrypt,
cookie_name
}
//这里是
_app.js:
function MyApp(pageProps){
......
}
MyApp.getInitialProps = async (appContext ) => {
let authenticated = false;
const cookies = nookies.get(appContext.ctx)
const {router} = appContext
// console.log(router.pathname)
if(cookies[cookie_name]){
const state = decrypt(cookies[cookie_name])
authenticated = state.token?true:false
}else{
if(router.pathname !== '/login'){
//判断如果没有cookie,就跳转到login
console.log(router.pathname, appContext.ctx.res)
appContext.ctx.res.writeHead(302, {location: '/login'})
appContext.ctx.res.end()
}
}
const appProps = await App.getInitialProps(appContext);
return { ...appProps, authenticated };
};
本文由 admin 创作,采用 知识共享署名4.0 国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
最后编辑时间为: Apr 25, 2021 at 10:51 am