Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question: Will this package work with Vue/React? #147

Open
mirkin-pixel opened this issue Sep 22, 2024 · 2 comments
Open

Question: Will this package work with Vue/React? #147

mirkin-pixel opened this issue Sep 22, 2024 · 2 comments

Comments

@mirkin-pixel
Copy link

Can this package work with VueJS/React in combination with Inertia? I only read information about blade.

@upwebdesign
Copy link
Contributor

@mirkin-pixel I don’t see why not.

@asugai
Copy link

asugai commented Dec 10, 2024

@mirkin-pixel - I was able to get things to work with this library but it was a bit of a hack and I was using Inertia / Vue3.

  • I added a passthrough to the view for the URL vars SAMLRequest and RelayState. My controller for login has these 2 routes login and login.auth
public function login()
{
    if (Auth::check()) {
        return redirect()->route('home');
    }

    return Inertia::render('Auth/Login', array_filter([
        'samlRequest' => request('SAMLRequest'),
        'relayState' => request('RelayState'),
    ]));
}

public function auth(Request $request)
{
    $request->validate([
        'email' => [
            'required',
            'email',
            'exists:users,email',
        ],
        'password' => 'required|min:8',
    ]);

    $user = User::where('email', $request->email)->first();

    if (! Hash::check($request->password, $user->password)) {
        throw ValidationException::withMessages([
            'form' => ['Incorrect credentials. Please try again.'],
        ]);
    }

    Auth::login($user, true);
}
  • On my Vue login page (resources/js/Pages/Auth/Login.vue), I made the form submit via POST after doing a check via Axios
<script setup>
import { useForm } from '@inertiajs/vue3';
import { ref } from 'vue';

const props = defineProps({
  samlRequest: [String, null],
  relayState: [String, null],
});

const form = useForm({
  email: '',
  password: '',
});

const formRef = ref(null);

const submit = () => {
  axios.post(route('login.auth'), {
    email: form.email,
    password: form.password
  }).then(response => {
    if (props.samlRequest && props.relayState) {
      // Create and submit form for SAML
      formRef.value.setAttribute('method', 'POST');
      formRef.value.setAttribute('action', route('login.auth'));
      formRef.value.submit();
    } else {
      form.password = '';
      window.location.href = route('auth.heypeers');
    }
  }).catch(error => {
    if (error.response) {
      // Convert array errors to string
      const errors = {};
      Object.keys(error.response.data.errors).forEach(key => {
        errors[key] = error.response.data.errors[key][0]; // Take first error message
      });
      form.errors = errors;
    }
  });
};
</script>

<template>
  <div>
    <form ref="formRef" @submit.prevent="submit" class="space-y-2">
      <div>
        <h1 class="text-2xl font-bold">Login</h1>
      </div>

      <template v-if="samlRequest && relayState">
        <input type="hidden" name="SAMLRequest" :value="samlRequest">
        <input type="hidden" name="RelayState" :value="relayState">
        <input type="hidden" name="_token" :value="$page.props.csrf_token">
      </template>

      <div>
        <label class="form-control w-full">
          <div class="label">
            <span class="label-text text-xs">Email</span>
          </div>
          <input required name="email" type="email" class="input input-bordered w-full" placeholder="[email protected]" v-model="form.email" :class="{ 'input-error': form.errors.email }" />
        </label>
        <div v-if="form.errors.email" class="label">
          <span class="label-text-alt text-red-600">{{ form.errors.email }}</span>
        </div>
      </div>

      <div>
        <label class="form-control w-full">
          <div class="label">
            <span class="label-text text-xs">Password</span>
          </div>
          <div class="relative">
            <input :type="showPassword ? 'text' : 'password'" name="password" class="input input-bordered w-full" placeholder="Password" v-model="form.password" :class="{ 'input-error': form.errors.password }" />
            <button type="button" @click="showPassword = !showPassword" class="btn btn-ghost border-none btn-sm right-2 absolute top-2">
              <EyeIcon v-if="!showPassword" class="h-5 w-5" />
              <EyeSlashIcon v-else class="h-5 w-5" />
            </button>
          </div>
        </label>
        <div v-if="form.errors.password" class="label">
          <span class="label-text-alt text-red-600">{{ form.errors.password }}</span>
        </div>
      </div>

      <div class="pt-4">
        <button type="submit"
          :disabled="form.processing"
          class="btn btn-primary btn-block">
          Login
        </button>
      </div>
    </form>
  </div>
</template>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants