1.登录页面
完善登录页面 和注册差不多 直接copy signUpPage 内容 再稍微修改下
import { useState } from "react";
import { useAuthStore } from "../store/useAuthStore";
import { MessageSquare,Mail,Lock,Eye, EyeOff,Loader2} from "lucide-react";
import {Link} from "react-router-dom"
const LoginPage = () => {
const [showPassword, setShowPassword] = useState(false)
const[formData,setFormData] = useState({
email:"",
password:""
})
const {login,isLogging} = useAuthStore()
const handleSubmit = async (e) => {
e.preventDefault()
await login(formData)
}
return (
<div className="min-h-screen grid lg:grid-cols-2">
{/*left side*/}
<div className="flex flex-col justify-center items-center p-6 sm:p-12">
<div className="w-full mt-10">
{/* logo */}
<div className="text-center mb-8">
<div className="flex flex-col items-center gap-2 group">
<div className="size-12 rounded-xl bg-primary/10 flex items-center justify-center
group-hover:bg-primary/20 transition-colors">
<MessageSquare className="size-6 text-primary"></MessageSquare>
</div>
<h1 className="text-2xl font-bold mt-2">欢迎回来</h1>
<p className="text-base-content/60">登录账户</p>
</div>
</div>
{/* form */}
<form onSubmit={handleSubmit} className="space-y-6">
<div className="form-control">
<label className="label">
<span className="label-text font-medium">邮箱</span>
</label>
{/* 输入框 */}
<div className="relative">
<div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<Mail className="size-5 text-base-content/40" />
</div>
<input
type="text"
className={`input input-bordered w-full pl-10`}
placeholder="请输入邮箱地址"
value={formData.email}
onChange={(e)=> setFormData({...formData,email:e.target.value})}
>
</input>
</div>
</div>
<div className="form-control">
<label className="label">
<span className="label-text font-medium">密码</span>
</label>
{/* 输入框 */}
<div className="relative">
<div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<Lock className="size-5 text-base-content/40" />
</div>
<input
type={showPassword ? "text" : "password"}
className={`input input-bordered w-full pl-10`}
placeholder="请输入密码"
value={formData.password}
onChange={(e)=> setFormData({...formData,password:e.target.value})}
>
</input>
<button
type="button"
className="absolute inset-y-0 right-0 pr-3 flex items-center"
onClick={()=> setShowPassword(!showPassword)}
>
{showPassword ? (<EyeOff className="size-5 text-base-content/40" />) : (<Eye className="size-5 text-base-content/40" />)}
</button>
</div>
</div>
<button
type="submit"
className="btn btn-primary w-full"
disabled={isLogging}
>
{isLogging ? (
<>
<Loader2 className="size-5 animate-spin"/>
Loading...
</>
):(
"登录"
)}
</button>
</form>
<div className="text-center">
<p className="text-base-content/60">
没有账号?{""}
<Link to="/signup" className="link link-primary">去注册</Link>
</p>
</div>
</div>
</div>
{/* right side */}
</div>
)
}
export default LoginPage
这时我们的前端页面就有了
2.测试
输入我们注册号的账号 登录 提示登录成功!
3.页面完善
现在我们登录和注册右侧缺一部分 我们补充上
在web下 新建components文件夹 再创建AuthImagePattern.jsx
const AuthImagePattern = ({title, subTitle}) => {
return (
<div className="hidden lg:flex items-center justify-center bg-base-200 p-12">
<div className="max-w-md text-center mt-10">
<div className="grid grid-cols-3 gap-3 mb-8">
{[...Array(9)].map((_,i)=>(
<div key={i}
className={`aspect-square rounded-2xl bg-primary/10 ${i%2===0?"animate-pulse":""}`}
>
</div>
))}
</div>
<h2 className="text-2xl font-bold mb-4">{title}</h2>
<p className="text-base-content/40">{subTitle}</p>
</div>
</div>
)
}
export default AuthImagePattern
然后在singUpPage 和 LoginPage 引入即可
import AuthImagePattern from "@/components/AuthImagePattern" 在right side使用
{/* right side */}
<AuthImagePattern title="加入我们" subTitle="发现新朋友,分享瞬间,享受乐趣,与你最心爱的人们保持联系。"/>
效果如图
4.认证优化
问题思考 当我们用户已经登录了 登录token没有过期 这时候我们应该让用户跳到首页 如果token过期了 就重定向到login 页面 这时获取用户信息之前就需要进行用户是否登录的验证 使用中间件来实现此功能
回到后端server 新建文件夹middleware 新建auth.middleware.js
在auth.route.js 中新增一个路由
// 身份验证
router.get('/check', protectRoute, checkAuth)
在auth.controller.js中 增加 checkAuth 方法 获取返回的用户信息
// 获取登录信息
export const checkAuth = (req,res) => {
try {
res.status(200).json(req.user)
} catch (err) {
res.status(500).json({ message: '内部服务器错误' })
}
}
useAuthStore.js 补充
isCheckingAuth: false, // 是否在获取用户信息中状态
// 获取用户信息方法
checkAuth: async() => {
// 获取当前用户信息
try {
const res = await axiosInstance.get('/auth/check')
set({authUser: res.data})
// 刷新页面 判断是否登录
get().connectSocket()
} catch (error) {
console.log("useAuthStore checkAuth error",error.message)
set({authUser: null})
} finally {
set({isCheckingAuth: false})
}
},
修改App.jsx
验证结果 如图checkAuth接口 获取到了用户信息跳转到了 homePage
ok 这篇 就这样把 有问题欢迎评论留言!!喜欢的来个3连 谢谢!! 下篇 咱实现导航栏和 修改个人信息