auth.tsx 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  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().set("access_token", JSON.stringify(nextToken));
  30. } else {
  31. setAuthStatus('fail');
  32. getGlobalStorage().remove("access_token");
  33. }
  34. setAccessToken(nextToken);
  35. };
  36. useEffect(() => {
  37. try {
  38. const token = JSON.parse(getGlobalStorage().getString("access_token")||"null");
  39. setToken(token);
  40. // eslint-disable-next-line @typescript-eslint/no-unused-vars
  41. }catch(e) {
  42. setToken(null);
  43. }
  44. }, []);
  45. return (
  46. <AuthContext.Provider
  47. value={{
  48. authStatus,
  49. setToken,
  50. }}
  51. >
  52. {children}
  53. </AuthContext.Provider>
  54. );
  55. }
  56. export function useAuthContext() {
  57. const context = useContext(AuthContext);
  58. if (!context) {
  59. throw new Error('useAuthContext must be used within an AuthProvider');
  60. }
  61. return context;
  62. }
  63. export function useAuth() {
  64. return useAuthContext();
  65. }
  66. export async function signIn(mobile: string, password: string) {
  67. const {
  68. token,
  69. expires_in
  70. } = await api.post<{
  71. token: string,
  72. expires_in: number,
  73. }>("/user/login", {
  74. mobile, password
  75. });
  76. return {
  77. token,
  78. expiresIn: expires_in
  79. } as AccessToken;
  80. }
  81. export async function smsSignIn(mobile: string, captcha: string) {
  82. const {
  83. token,
  84. expires_in
  85. } = await api.post<{
  86. token: string,
  87. expires_in: number,
  88. }>("/user/mobilelogin", {
  89. mobile, captcha
  90. });
  91. return {
  92. token,
  93. expiresIn: expires_in
  94. } as AccessToken;
  95. }
  96. export async function signUp(info: {
  97. mobile: string;
  98. captcha: string;
  99. password: string;
  100. name: string;
  101. email: string;
  102. }) {
  103. const {
  104. token,
  105. expires_in
  106. } = await api.post<{
  107. token: string,
  108. expires_in: number,
  109. }>("/user/register", info);
  110. return {
  111. token,
  112. expiresIn: expires_in
  113. } as AccessToken;
  114. }
  115. export async function signOut() {
  116. return api.get("/user/logout")
  117. }