最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

reactjs - Why is my Supabase Password Reset in React not verifying the session correctly? - Stack Overflow

programmeradmin3浏览0评论

I am working on a password reset feature for a flutter application. It sends the user an email which sends them to a website which should handle the password reset. However, I am having issues with Supabase session management and I am unable to update the user password.

Flutter function for sending the email.

Future<void> sendPasswordResetEmail(String email, BuildContext context) async {
  try {
    final response = await Supabase.instance.client.auth.resetPasswordForEmail(
      email,
      redirectTo: '',
    );
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(
        content: Text('Password reset email sent successfully', textAlign: TextAlign.center,),
        backgroundColor: const Color.fromARGB(255, 52, 157, 44),
      ),
    );
  } catch (e) {
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(
        content: Text('Failed to send password reset email: ${e.toString()}', textAlign: TextAlign.center,),
        backgroundColor: Colors.red,
      ),
    );
  }
}

The Button link that the email takes to

            <div style="text-align: center;">
                 <a 
                    href="{{ .ConfirmationURL }}#token={{ .Token }}&token_hash={{ .TokenHash }}&email={{ .Email }}" 
                    class="button"
                >
                    Reset Password
                </a>
            </div>

The inital part of the password reset (Assuming the error lies here)

  const [passwords, setPasswords] = useState({ password: '', confirmPassword: '' });
  const [message, setMessage] = useState({ type: '', text: '' });
  const [isLoading, setIsLoading] = useState(false);
  const [session, setSession] = useState(null);
  const [showPassword, setShowPassword] = useState(false);
  const [showConfirmPassword, setShowConfirmPassword] = useState(false);
  const [email, setEmail] = useState('');

  useEffect(() => {
    const searchParams = new URLSearchParams(window.location.search);
    const hashParams = new URLSearchParams(window.location.hash.substring(1));

    const searchError = searchParams.get('error');
    const hashError = hashParams.get('error');
    const errorDescription = searchParams.get('error_description') || hashParams.get('error_description');

    if (searchError || hashError) {
      setMessage({
        type: 'error',
        text: errorDescription || 'Invalid or expired reset link',
      });
      return;
    }

    const token = hashParams.get('token');
    const tokenHash = hashParams.get('token_hash');
    const hashEmail = hashParams.get('email');

    console.log('token:', token);
    console.log('token hash:', tokenHash);
    console.log('email:', hashEmail);

    if (!token || !tokenHash) {
      setMessage({
        type: 'error',
        text: 'Invalid reset link - missing required parameters',
      });
      return;
    }

    if (hashEmail) {
      setEmail(hashEmail);
    }

    // Immediately verify the OTP token for recovery
    const verifyRecoveryToken = async () => {
      const { data, error } = await supabase.auth.verifyOtp({
        email: hashEmail,
        token: token,
        type: 'recovery',
      });

      if (error) {
        console.error('Verification error:', error);
        setMessage({
          type: 'error',
          text: error.message || 'Invalid or expired reset link.',
        });
      } else {
        console.log('Verified session:', data);
        setSession(data);
        setMessage({
          type: 'success',
          text: 'Reset link verified. Please set your new password.',
        });
      }
    };

    verifyRecoveryToken();
  }, []);

The actual sending the request to the server.

  const handlePasswordReset = async (e) => {
    e.preventDefault();

    if (!session) {
      setMessage({
        type: 'error',
        text: 'No active session. Please request a new password reset.',
      });
      return;
    }

    setIsLoading(true);

    // Validate passwords before proceeding
    if (passwords.password !== passwords.confirmPassword) {
      setMessage({
        type: 'error',
        text: 'Passwords do not match.',
      });
      setIsLoading(false);
      return;
    }

    if (passwords.password.length < 6) {
      setMessage({
        type: 'error',
        text: 'Password must be at least 6 characters long.',
      });
      setIsLoading(false);
      return;
    }

    try {
      // Update the password using the verified session
      const { error: updateError } = await supabase.auth.updateUser({
        password: passwords.password,
      });

      if (updateError) throw updateError;

      setMessage({
        type: 'success',
        text: 'Password updated successfully!',
      });

      // Clear the form
      setPasswords({ password: '', confirmPassword: '' });

      // Redirect after success (adjust the URL as needed)
      setTimeout(() => {
        window.location.href = 'invoiceup://';
      }, 2000);
    } catch (error) {
      console.error('Password update error:', error);
      setMessage({
        type: 'error',
        text: error.message || 'Failed to update password. Please try again.',
      });
    } finally {
      setIsLoading(false);
    }
  };

EDIT 1: I seem to be getting an error when trying to access supabase with my client

{"message":"No API key found in request","hint":"No `apikey` request header or url param was found."}

This is my code for it

import { createClient } from '@supabase/supabase-js';

const supabaseUrl = '';
const supabaseAnonKey = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';

// Initialize Supabase client with enhanced auth configuration
export const supabase = createClient(supabaseUrl, supabaseAnonKey);

I also saw someone say it must be due to supabase allowed sites however the https:// is included therefore it should work. I also have allowed all pages of my site to be allowed auth data.
https://*.mysite.co.uk/*
added in. the url settings of my project

I tried to send myself the password reset email. It sent correctly, the link looks something like this

#token=444555&token_hash=pkce_f3fc77a38dc132a94641a1ad0bd7051baa9addea9f85xxxxxxx&email=myemail%40outlook

How the variables are: token: 444555 token hash: pkce_f3fc77a38dc132a94641a1ad0bd7051baa9addea9f857xxxxxxxxxxxx e9192ac6.0eb2f27f.js:1 email: [email protected]

Instead of a successful sign in i got errors:

Failed to load resource: the server responded with a status of 403 ()Understand this errorAI

** Failed to load resource: the server responded with a status of 403 ()Understand this errorAI Verification error: AuthApiError: Token has expired or is invalid**

发布评论

评论列表(0)

  1. 暂无评论