auth.tsx 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. import React, { createContext, useContext, useEffect, useState } from 'react';
  2. import api, { setAccessToken } from './api';
  3. import { getGlobalStorage } from './storage';
  4. export interface AccessToken {
  5. token: string;
  6. expiresIn: number;
  7. tokenType?: string;
  8. scope?: string;
  9. expiresAt: number;
  10. }
  11. interface AuthContextType {
  12. authStatus: 'auth' | 'loading' | 'fail';
  13. setToken: (token: AccessToken | undefined | null) => void;
  14. }
  15. const AuthContext = createContext<AuthContextType>(null!);
  16. export function AuthProvider({ children }: { children: React.ReactNode }) {
  17. const [authStatus, setAuthStatus] = useState<'auth' | 'loading' | 'fail'>('loading');
  18. const setToken = (nextToken: AccessToken | undefined | null) => {
  19. // tokenCache = nextToken;
  20. if (nextToken && nextToken.token && nextToken.expiresIn) {
  21. // if (!tokenCache.expiresAt) {
  22. nextToken.expiresAt = nextToken.expiresIn + Date.now() / 1000;
  23. // }
  24. } else {
  25. nextToken = null;
  26. }
  27. if (nextToken) {
  28. setAuthStatus('auth');
  29. getGlobalStorage().setObject("access_token", nextToken, nextToken.expiresIn);
  30. } else {
  31. setAuthStatus('fail');
  32. getGlobalStorage().remove("access_token");
  33. }
  34. setAccessToken(nextToken);
  35. };
  36. useEffect(() => {
  37. const token = getGlobalStorage().getObject("access_token");
  38. setToken(token);
  39. }, []);
  40. return (
  41. <AuthContext.Provider
  42. value={{
  43. authStatus,
  44. setToken,
  45. }}
  46. >
  47. {children}
  48. </AuthContext.Provider>
  49. );
  50. }
  51. export function useAuthContext() {
  52. const context = useContext(AuthContext);
  53. if (!context) {
  54. throw new Error('useAuthContext must be used within an AuthProvider');
  55. }
  56. return context;
  57. }
  58. export function useAuth() {
  59. return useAuthContext();
  60. }
  61. export async function signIn(mobile: string, password: string) {
  62. const {
  63. token,
  64. expires_in
  65. } = await api.post<{
  66. token: string,
  67. expires_in: number,
  68. }>("/user/login", {
  69. mobile, password
  70. });
  71. return {
  72. token,
  73. expiresIn: expires_in
  74. } as AccessToken;
  75. }
  76. export async function smsSignIn(mobile: string, captcha: string) {
  77. const {
  78. token,
  79. expires_in
  80. } = await api.post<{
  81. token: string,
  82. expires_in: number,
  83. }>("/user/mobilelogin", {
  84. mobile, captcha
  85. });
  86. return {
  87. token,
  88. expiresIn: expires_in
  89. } as AccessToken;
  90. }
  91. export async function signUp(info: {
  92. mobile: string;
  93. captcha: string;
  94. password: string;
  95. name: string;
  96. email: string;
  97. }) {
  98. const {
  99. token,
  100. expires_in
  101. } = await api.post<{
  102. token: string,
  103. expires_in: number,
  104. }>("/user/register", info);
  105. return {
  106. token,
  107. expiresIn: expires_in
  108. } as AccessToken;
  109. }
  110. export async function signOut() {
  111. return api.get("/user/logout")
  112. }