#nuxt/auth $auth.loggedIn is not reactive - nuxt-auth

I have two problems with #nuxt/auth, the first is that $auth.loggedIn is not reacting to change, I have the below code for my app and when I login or logout I have to chage the route in order for the header to reacte and change state (hide or show login/register and user info) below is my code for template.
<userdown #logout="$auth.logout()" v-if="$auth.loggedIn"/>
<div v-else>
<nuxt-link :to="localePath('/login')" class="text-white mx-4">
{{$t("links.login")}}
</nuxt-link>
<nuxt-link :to="localePath('/register')" class="text-white mx-4">
{{$t("links.register")}}
</nuxt-link>
</div>
The second one is that the redirect is not working automatically (example when login it should redirect to home page but nothing happen)
auth: {
strategies: {
local: {
token: {
property: 'token'
},
user: {
property: 'user'
},
endpoints: {
login: { url: '/api/auth/login', method: 'post' },
logout: { url: '/api/auth/logout', method: 'post' },
user: { url: '/api/auth/user', method: 'get' }
}
}
},
redirect: {
login: '/login',
logout: '/',
callback: '/login',
home: '/'
}
}

I've encountered the same issue in production. Locally, everything works as expected. Anyways, I've ended up using:
v-show="$store.state.auth.loggedIn"

Related

Laravel Passport authentication : how to use code and state?

I'm authenticating to Laravel (7.3) Passport with the following configuration:
nuxt.config.js
auth: {
redirect: {
login: '/login',
logout: '/login',
home: '/'
},
strategies: {
'laravel.passport': {
url: 'http://laravel.test',
client_id: '2',
client_secret: 'S0gpcgfIDgbvIHCL3jIhSICAiTsTUMOR0k5mdaCi',
redirect_uri: 'http://localhost:3000'
}
}
}
Authentication method in pages/login.vue:
async nuxtLaravelPassport() {
try {
const response = await this.$auth
.loginWith('laravel.passport')
.then(result => {
console.log(result)
})
} catch (err) {
console.log(err)
}
},
It brings me to the authentication page of Laravel, then I log in and I'm redirected to my Nuxt.js home page with a code and state as parameters.
What should I do with these code and state ? Get a token ? If yes, how ?

Redirect to requested URL if already authorized in VueJS Router

I'm trying to understand the VueJS router model by building this tutorial app. The app redirects you to the home page if you try to open a direct link like https://example.com/meetups even if you already logged in and authorized. Why is that and how to open the requested URL instead?
auth-guard.js
import {store} from '../store'
export default (to, from, next) => {
if (store.getters.user) {
next()
} else {
next('/signin')
}
}
index.js
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/signup',
name: 'Signup',
component: Signup
},
{
path: '/signin',
name: 'Signin',
component: Signin
},
{
path: '/meetups',
name: 'Meetups',
component: Meetups,
beforeEnter: AuthGuard
},
{
path: '/meetup/new',
name: 'CreateMeetup',
component: CreateMeetup,
beforeEnter: AuthGuard
},
{
path: '/meetups/:id',
name: 'Meetup',
props: true,
component: Meetup,
beforeEnter: AuthGuard
},
{
path: '/profile',
name: 'Profile',
component: Profile,
beforeEnter: AuthGuard
}
],
mode: 'history'
})
The auth-guard.js will redirect someone to the sign in page if the store user is null.
When does the store user get updated?
Inside main.js:
firebase.auth().onAuthStateChanged((user) => {
if (user) {
this.$store.dispatch('autoSignIn', user)
}
})
the onAuthStateChanged method is async, meaning that it might finish executing after you have asked the browser to go to a page that is guarded by auth-guard.js.
This is mostly what happens if you open a new tab or window and type in the url of a guarded page.
This behaviour would work properly if first, the site is fully loaded on an unguarded page (let's say /signin) and then the user would try to click on a guarded page (let's say /meetups). By the time the user clicks on the link, there is a good chance the onAuthStateChanged method will have returned and commited to the store ( this.$store.dispatch('autoSignIn', user) ), allowing onAuthStateChanged to execute properly.
EDIT
One way to solve this problem would be to instanciate the Vue app only once the onAuthStateChanged has returned a user like so:
main.js
firebase.initializeApp({
apiKey: 'AIzaSyCFYWd6FpR53u4hSPXQSjOYeZNPF1FxG2M',
authDomain: 'yt-devmeetup.firebaseapp.com',
databaseURL: 'https://yt-devmeetup.firebaseio.com',
projectId: 'yt-devmeetup',
storageBucket: 'gs://yt-devmeetup.appspot.com'
})
firebase.auth().onAuthStateChanged((user) => {
if (user) {
store.dispatch('autoSignIn', user)
store.dispatch('fetchUserData')
}
new Vue({
el: '#app',
router,
store,
render: h => h(App),
created() {
this.$store.dispatch('loadMeetups')
}
})
})

AngularJS Devise authorization

I'm trying to add authorization functionality to my app, sow for example when I want to go to /admin/posts/create it will redirect me to /login if I'm not already logged in.
My angular module
angular.module('flapperNews', ['ui.router', 'templates', 'ngResource', 'formly', 'formlyBootstrap', 'ngMessages', 'Devise'])
I'm using this service
angular.module('flapperNews')
.factory('authorization', [
'$state',
'Auth',
'$location',
function($state, Auth, $location) {
return {
authorize: function() {
var isAuthenticated = Auth.isAuthenticated();
if (isAuthenticated === false) {
$state.go('login');
}
}
};
}
]);
These are my routes
$stateProvider.state('home', {
url: '/',
controller: 'PostsCtrl',
templateUrl: 'posts/_posts.html'
});
$stateProvider.state('admin', {
abstract: true,
resolve: {
authorize: ['authorization', function(authorization) {
return authorization.authorize();
}]
},
template: '<div ui-view />'
});
$stateProvider.state('postsCreate', {
parent: 'admin',
url: '/admin/posts/create',
controller: 'PostsCtrl as vm',
templateUrl: 'posts/create.html'
});
Through this link I'm trying to access route where I shouldn't be able to get
<a ui-sref="postsCreate" class="btn btn-primary">Create a post</a>
I don't get any errors and I end up in section which I should be able to access.

AngularJS MVC 4 routing, html5 hashbang urls

I have angularjs and mvc4 app. For using disqus I enabled hashbang and html5Mode url.
With html5 mode, server side url rewriting needs to be fixed. otherwise a full page refresh leads to 404 error.
The entry point of my application is Index.chtml in home controller and it uses _layout.chtml (for bundling and minification.)
My webconfig route is :
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{*url}",
defaults: new { controller = "Home", action = "Index"},
namespaces: new[] { "Flashspark.Controllers" });
and my AngularJS config is:
(function () {
'use strict';
var app = angular.module('app');
// Collect the routes
app.constant('routes', getRoutes());
// Configure the routes and route resolvers
app.config(['$routeProvider', '$locationProvider', 'routes', routeConfigurator]);
function routeConfigurator($routeProvider,$locationProvider, routes) {
routes.forEach(function (r) {
$routeProvider.when(r.url, r.config);
$locationProvider.html5Mode('true').hashPrefix('!');
});
$routeProvider.otherwise({ redirectTo: '/' });
}
// Define the routes
function getRoutes() {
return [
{
url: '/',
config: {
templateUrl: 'app/thoughts/thoughts.html',
title: 'thoughts',
settings: {
nav: 1,
content: '<i class="fa fa-book"></i> Thoughts'
}
}
}, {
url: '/faq',
config: {
title: 'faq',
templateUrl: 'app/faq/faq.html',
settings: {
nav: 2,
content: '<i class="fa fa-info"></i> FAQ'
}
}
},
{
url: '/timeline',
config: {
templateUrl: 'app/timeline/timeline.html',
title: 'timeline',
settings: {
nav: 3,
content: '<i class="fa fa-arrows-h"></i> Timeline'
}
}
},
{
url: '/about',
config: {
templateUrl: 'app/about/about.html',
title: 'contact',
settings: {
nav: 4,
content: '<i class="fa fa-list fa-1x"></i> About'
}
}
},
{
url: '/thoughts/:article',
config: {
templateUrl: 'app/article/article.html',
title: 'article',
}
}
];
}
=================================================================================
THE PROBLEM I AM HAVING:
With this configuration, All the routes which are only 1 deep work without any issues
like:
/faq , /timeline
even after refresh, the url's are preserved.
However for URL's like:
/thoughts/:articleid (2 deep)
the styling for the whole app is stripped out when I refresh from this page.
You need to have to a default route for thoughts
{
url: '/thoughts',
config: {
templateUrl: 'app/article/article.html',
title: 'article',
}
}

How to fetch index data in Angular using rails server

I am starting with Angularjs + rails backend and trying to fetch users data from the server - equivalent to to controller/index action in rails.
I have followed several tutorials and found this code as the most clear one....
questions
1. How to properly link angular module into views ?
2. How to fetch data using typeahead and sample data in this post.
here is plunker version of the code
Code is as follows:
views
<div ng-app='users'>
<div class='container-fluid' ng-controller="UsersIndexCtrl">
<pre>Model: {{result | json}}</pre>
<input type="text" ng-model="result" typeahead="suggestion for suggestion in users($viewValue)">
</div>
</div>
controller
<script>
// ['ui.bootstrap', 'ngResource'])
var app = angular.module('users', ['ui.bootstrap', 'ngResource']);
// factory - resources users
// equivalent to rails users/index
app.factory('Users', function($resource) {
return $resource('/users.json', {}, {
index: { method: 'GET', isArray: true}
});
});
// factory - user resource
// equivalent to users show, update
app.factory('User', function($resource) {
return $resource('/users/:user_id.json', {}, {
show: { method: 'GET' },
update: { method: 'PUT' }
});
});
// controller - users/ index
// equivalent to rails controller rails/index
var UsersIndexCtrl = function($scope, users) {
$scope.users = users;
};
</script>
and I am stack here, as I am getting this error:
Error: Unknown provider: usersProvider <- users
The goal of this code is to use typehead and provide data to the user.
My '/users.json' url is as follows:
[{"full_name":"Lia Cartwright","id":1,"image_url":"no-icon.jpg"},{"full_name":"Hilton Turner","id":2,"image_url":"no-icon.jpg"},{"full_name":"Aubrey Barrows","id":3,"image_url":"no-icon.jpg"},{"full_name":"Donnie Kris","id":4,"image_url":"no-icon.jpg"},{"full_name":"Eryn Rath","id":5,"image_url":"no-icon.jpg"},{"full_name":"Caden Fay","id":6,"image_url":"no-icon.jpg"},{"full_name":"Arlie Tromp","id":7,"image_url":"no-icon.jpg"},{"full_name":"Rico Klein","id":8,"image_url":"no-icon.jpg"},{"full_name":"Gudrun Dare","id":9,"image_url":"no-icon.jpg"},{"full_name":"Nathan Langworth","id":10,"image_url":"no-icon.jpg"},{"full_name":"Deanna Stroman","id":11,"image_url":"no-icon.jpg"},{"full_name":"Shania Stroman","id":12,"image_url":"no-icon.jpg"},{"full_name":"Lupe Harvey","id":13,"image_url":"no-icon.jpg"},{"full_name":"Constance Armstrong","id":14,"image_url":"no-icon.jpg"},{"full_name":"Reagan Tremblay","id":15,"image_url":"no-icon.jpg"},{"full_name":"Murray Sipes","id":16,"image_url":"no-icon.jpg"},{"full_name":"Dandre Klocko","id":17,"image_url":"no-icon.jpg"},{"full_name":"Haylee Monahan","id":18,"image_url":"no-icon.jpg"},{"full_name":"Florence Harber","id":19,"image_url":"no-icon.jpg"},{"full_name":"Norberto Hoppe","id":20,"image_url":"no-icon.jpg"}]
You must inject Users not users, it's case sensitive.
Side notes:
No need to create two models, replace:
app.factory('Users', function($resource) {
return $resource('/users.json', {}, {
index: { method: 'GET', isArray: true}
});
});
app.factory('User', function($resource) {
return $resource('/users/:user_id.json', {}, {
show: { method: 'GET' },
update: { method: 'PUT' }
});
});
with:
app.factory('User', function($resource) {
return $resource("users/:id", { id: '#id' }, {
index: { method: 'GET', isArray: true, responseType: 'json' },
show: { method: 'GET', responseType: 'json' },
update: { method: 'PUT', responseType: 'json' }
});
})
Other thing, in your controller, do:
var UsersIndexCtrl = function($scope, User) {
$scope.users = User.index();
};
Last thing, consider using: Angular Rails resource

Resources