Nest Authbeta

Authentication

Signup, login, passwordless, social, logout, password reset, and verification — all through `useNestAuth()`.

Every action on this page comes from the useNestAuth() hook. Each method is async (returns a Promise) and updates the provider's state — status, sessionData, isAuthenticated, error — on success or failure, so your screens re-render automatically.

import { useNestAuth } from '@ackplus/nest-auth-react-native';
 
const {
  login, signup, logout, logoutAll, refresh,
  passwordlessSend,
  forgotPassword, verifyForgotPasswordOtp, resetPassword, changePassword,
  sendEmailVerification, verifyEmail,
  sendPhoneVerification, verifyPhone,
  verifySession, getSessionData,
} = useNestAuth();

Sign up

signup takes an email or phone plus a password:

import { useState } from 'react';
import { View, TextInput, Button } from 'react-native';
import { useNestAuth } from '@ackplus/nest-auth-react-native';
 
export function SignupScreen() {
  const { signup, isLoading } = useNestAuth();
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
 
  const onSubmit = async () => {
    await signup({ email, password });
  };
 
  return (
    <View>
      <TextInput value={email} onChangeText={setEmail} autoCapitalize="none" />
      <TextInput value={password} onChangeText={setPassword} secureTextEntry />
      <Button title="Create account" onPress={onSubmit} disabled={isLoading} />
    </View>
  );
}

Email & password login

Pass providerName: 'email' with credentials: { email, password }:

import { useState } from 'react';
import { View, TextInput, Button, Text } from 'react-native';
import { useNestAuth } from '@ackplus/nest-auth-react-native';
 
export function LoginScreen() {
  const { login, error, isLoading } = useNestAuth();
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
 
  const onSubmit = async () => {
    await login({ providerName: 'email', credentials: { email, password } });
    // on success `isAuthenticated` flips and `sessionData` populates
  };
 
  return (
    <View>
      <TextInput value={email} onChangeText={setEmail} autoCapitalize="none" />
      <TextInput value={password} onChangeText={setPassword} secureTextEntry />
      {error ? <Text>{String(error)}</Text> : null}
      <Button title="Sign in" onPress={onSubmit} disabled={isLoading} />
    </View>
  );
}

login also accepts createUserIfNotExists? and tenantId?. The full shape is login({ providerName?, credentials, createUserIfNotExists?, tenantId? }).

If the response has isRequiresMfa === true, the account has two-factor enabled and login isn't finished yet — see MFA & tenancy.

Passwordless login

A two-step flow. First send a one-time code over email or sms:

const { passwordlessSend } = useNestAuth();
 
await passwordlessSend({ identifier: 'user@example.com', channel: 'email' });

Then complete login with the code the user received, using the passwordless provider:

const { login } = useNestAuth();
 
await login({
  providerName: 'passwordless',
  credentials: {
    identifier: 'user@example.com',
    code: '123456',
    channels: ['email'],
  },
});

Use channel: 'sms' (and channels: ['sms']) to deliver and verify the code by text instead.

Social login (native — no browser)

Google and Apple sign-in run through the platform's native flow, not a browser or webview. The SDK ships helper wrappers — signInWithGoogle and signInWithApple — that drive the native module and exchange the resulting token with your backend. You inject the native module, so this package carries no native dependency of its own.

Google

Install and configure @react-native-google-signin/google-signin. Set webClientId to your web OAuth client ID so the returned ID token's audience matches the backend's google.clientId (or a google.audiences entry).

import { GoogleSignin } from '@react-native-google-signin/google-signin';
import { useNestAuth, signInWithGoogle } from '@ackplus/nest-auth-react-native';
 
GoogleSignin.configure({ webClientId: 'YOUR_WEB_CLIENT_ID.apps.googleusercontent.com' });
 
export function GoogleButton() {
  const { client } = useNestAuth();
  return <Button title="Continue with Google" onPress={() => signInWithGoogle(client, GoogleSignin)} />;
}

Apple

Use expo-apple-authentication (Expo) or @invertase/react-native-apple-authentication. signInWithApple presents the native sheet, forwards the identityToken, and passes the user's name (Apple returns it only on the first sign-in) plus an optional nonce for replay protection.

import * as AppleAuthentication from 'expo-apple-authentication';
import { useNestAuth, signInWithApple } from '@ackplus/nest-auth-react-native';
 
export function AppleButton({ nonce }: { nonce?: string }) {
  const { client } = useNestAuth();
  return (
    <AppleAuthentication.AppleAuthenticationButton
      buttonType={AppleAuthentication.AppleAuthenticationButtonType.SIGN_IN}
      buttonStyle={AppleAuthentication.AppleAuthenticationButtonStyle.BLACK}
      onPress={() => signInWithApple(client, AppleAuthentication, { nonce })}
    />
  );
}

Backend config. Native Apple identityTokens are verified against Apple's JWKS — no client secret is needed for mobile. Set apple.audiences to include your iOS Bundle ID alongside the web Service ID (clientId). For Google, add any native client IDs to google.audiences if your ID tokens aren't issued for the web client ID. The backend verifies the token, provisions the account on first sign-in, and links the identity atomically.

If you obtain a token another way, call the client directly:

const { client } = useNestAuth();
await client.socialLogin('google', idToken, { type: 'idToken' });
await client.socialLogin('apple', identityToken, { nonce, name: 'Ada Lovelace' });

Logout

logout ends the current session; logoutAll revokes every session for the user (all devices):

const { logout, logoutAll } = useNestAuth();
 
await logout();      // this device
await logoutAll();   // every device

Both clear the stored tokens through your storage adapter, so the next launch starts unauthenticated.

Refresh & session checks

The client auto-refreshes near expiry, but you can also drive it manually:

const { refresh, verifySession, getSessionData } = useNestAuth();
 
await refresh();         // force a token refresh
await verifySession();   // re-validate the session with the backend
await getSessionData();  // re-fetch the current session user

isLoadingSessionData is true while getSessionData is in flight, if you want to show a spinner.

Password reset (forgot password)

Three steps: request a code, verify it to get a reset token, then set the new password.

const { forgotPassword, verifyForgotPasswordOtp, resetPassword } = useNestAuth();
 
// 1. send the reset code (by email or phone)
await forgotPassword({ email: 'user@example.com' });
 
// 2. verify the code — returns a short-lived reset token
const { token } = await verifyForgotPasswordOtp({
  email: 'user@example.com',
  code: '123456',
});
 
// 3. set the new password using that token
await resetPassword({ token, newPassword: 'a-new-strong-password' });

For phone-based reset, pass phone instead of email to forgotPassword and verifyForgotPasswordOtp.

Change password (while signed in)

When the user is authenticated and knows their current password:

const { changePassword } = useNestAuth();
 
await changePassword({
  currentPassword: 'old-password',
  newPassword: 'new-strong-password',
});

Email verification

Send a verification code, then confirm it:

const { sendEmailVerification, verifyEmail } = useNestAuth();
 
await sendEmailVerification();        // optionally pass a DTO
await verifyEmail({ code: '123456' });

Phone verification

Same shape, for the user's phone number:

const { sendPhoneVerification, verifyPhone } = useNestAuth();
 
await sendPhoneVerification();        // optionally pass a DTO
await verifyPhone({ code: '123456' });
  • MFA & tenancy — finish MFA-gated logins and switch tenants.
  • Hooks & guards — read user/role/permission state and protect screens.

On this page