Phalcon Micro - Secure Routes - phalcon

I've just started trying out Phalcon Micro for my RestAPI's.
Everything is working well, however I can't seem to figure out how to secure some routes, but not others.
Has anyone had any experience in this area? - I've come from Slim where I can just pass functions in the actual route definitions.
Cheers,
Ben

Here is one way to achieve this, you can use beforeMatch() on your route, as you are used to with Slim.
$router->add('/koshnitsa', 'Basket::index')->setName('basket')->beforeMatch(
function ($uri, $route) {
// Replace with your conditions
if ($https) {
return true;
}
return false;
}
);
You can even make your own filter, read more in the docs.

Also you can use more generic approach with events or middleware:
https://docs.phalconphp.com/en/3.0.0/reference/micro.html#micro-application-events
https://docs.phalconphp.com/en/3.0.0/reference/micro.html#middleware-events

Related

Is it possible to use nuxt fetch() and set the values in head()?

The problem is that head() seems to be executed before async fetch(), which causes errors when trying to insert page's metadata and title. I KNOW asyncData exists, but the fact that it blocks page loading at a route transition level makes it provide such a HORRIBLE user experience (in a mobile device with bad connection, page transition can stay blocked for seconds) and reminds of old PHP rendered websites, not a modern SPA. Nuxt fetch() in the other hand, while still server side rendering the page, exposes $fetchState.pending and makes possible to exhibit an instant page transition showing the page skeleton, for example (consequently making the user experience better). The only problem i am having is this one with head() data. Is this problem solvable or just one unsolvable drawback of using fetch() instead of asyncData()?
Important Note: I am referring to Nuxt's new fetch method, not the legacy one.
example code that doesn't work:
data() {
return {
car: null,
}
},
async fetch() {
this.car = await this.$axios.$get('/cars/' + this.$route.params.id)
},
head() {
return {
title: this.car.name,
}
},
My colleague did a talk a few weeks ago, speaking about SEO in general, here is related section: https://youtu.be/W9camkXNjkw?t=920
Looking at all my given answers regarding SEO and also Github issues, all examples are using asyncData or some static approach.
When you think about it, I'm not sure how you could generate something on SSR, while being totally dynamic + non-blocking.
Either you know it ahead of time and can generate the OG tags, or you don't if it's totally volatile.

Retrieve a file before anything else happens

Iʼm creating a simple SPA that will retrieve data from an API. The page itself is served by a separate backend process which is the only entity that knows the API address. As such, it also provides an endpoint that, among other things, returns the API URL:
{
"api_url_base": "http://api.example.org/v1"
}
This is needed because the whole thing is deployed at multiple sites where we donʼt have control over DNS records and it may or may not be easy to derive the API URL from the front end appʼs.
Now i need to write my Vue app so nothing can happen until i fetch and process this file. To achieve that, i added to the appʼs beforeMount method:
this.settings = axios.get('/settings.json');
and in my componentsʼ beforeMount:
var comp = this;
app.__vue__.settings.then((response) => {comp.url = response.data.api_url;});
However,it seems the componentʼs beforeMounted often runs before the appʼs, and app. __vue__.settings is undefined when i get to the componentʼs beforeMount.
Where do i go wrong? Am I putting things at wrong places, or is my approach completely wrong?
You can fetch data before mount the vue app.
axios.get('/settings.json').then(response => {
// do something with response
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
}
One way (as suggested in the previous answer) is to make one more call, before anything else. However it brings numerous downsides.
Let me just say that it freezes the loading of your application until the response is received.
There is hope as you can cleverly use (f.e.) good ol' dependency injection to pass the required data to your app.
This article answers this question fully and completely: https://codeburst.io/passing-configuration-to-vue-js-1b96fa8f959

"Default Apollo Queries" VS "AsyncData" (Nuxt.js)

I'm building a site with Nuxt/Vue, and it's using a GraphQL backend API. We access this using the Apollo module for Nuxt.
In a page component, you can do this (I think this is called a Smart Query, but I'm not sure):
apollo: {
pages: {
query: pagesQuery,
update(data) {
return _get(data, "pageBy", {});
}
},
}
}
But you can also do the query like this I think, using the Nuxt asyncData hook:
asyncData(context) {
let client = context.app.apolloProvider.defaultClient;
client.query({query, variables})
.then(({ data }) => {
// do what you want with data
});
}
}
I'm not sure what the difference is between these two ways, and which is better. Does anyone know? I couldn't find an explanation in the docs anywhere.
Yeah, good question. The code you have shown at the top is indeed called a Smart Query. In fact
Each query declared in the apollo definition (that is, which doesn't
start with a $ char) in a component results in the creation of a smart
query object.
A nuxt project using the #nuxtjs/apollo module can use these out of the box. The beauty of the smart query is the options that it comes with and one of these is the 'prefetch' option. This, as it sounds, allows prefetching and is by default set to true. It can also accept a variables object or a function. You can see the docs here.
This means that the outcome of a smart query or an asyncData query will essentially be the same. They should be resolved in the same timeframe.
So why choose one or the other? This would probably be down to preference, but with all the options that a smart query allows you can do a lot more, and you can include subscriptions which might not be possible in asyncData.
More about smart queries here.

Provide / Find all remote routes

We have a number of separate laravel projects using routes to implement online api's. I am creating a separate laravel 5 project to 'collect' these routes.
As theses routes can change over time, I thought it would be a sensible option to create a route in each separate laravel project which returned a json of available routes in that project. Something like;
App\Http\Controllers\RoutesController#routes
with method
public function routes(Request $request)
{
$routeCollection = Route::getRoutes();
$routePaths = [];
foreach ($routeCollection as $route) {
$routePaths[] = $route->getPath();
}
return response()->json(['routes'=> $routePaths], 200);
}
Then the collecting app can simply query this same route for each individual project url. I think this feels like a fairly good solution. However I want to check before I implement this that I am not reinventing the wheel.
Does laravel have a way to 'broadcast' all publicly available routes? - or some way to scan for all available routes from a given url? Or are there better ways of doing this?
You can get a list of all routes in the same way that the artisan route:list does, you can see the function you can call here:
https://github.com/laravel/framework/blob/6e31296d6531d0148aadf09c5536b89dda49dc27/src/Illuminate/Routing/RouteCollection.php#L243

Mocking out AJAX calls with Dojo XHR

I'm attempting to mock the response of a dojo xhr request, but I haven't found a good solution.
Ideally, I'd like to see a solution similar to the jQuery mockjax plugin where I can set a specific call based on a url, e.g.:
$.mockjax({
url: '/restful/fortune',
responseTime: 750,
responseText: {
status: 'success',
fortune: 'Are you a turtle?'
}
});
My initial thought was to utilize the "/dojo/io/send" channel, but I haven't been able to get a modified response to be loaded after modifying the dojo Deferred object.
The other thought is to use a pass-through method that would determine if an actual xhr request should be made, e.g.:
function xhrRequest(xhrArgs) {
if(shouldMock) {
var fakeReturnJson = dojo.toJson({
howdy: "that's odd!",
isStrange: false
});
return fakeReturnJson;
} else {
dojo.xhr(xhrArgs);
}
}
Can someone tell me the best way to go about mocking dojo xhr calls?
Thanks!
It's an old question, but I think you should do your mocking using Sinon.js
However you will need to put the following:
has: { native-xhr2: false }
into your dojoConfig for it to work in 1.8
I haven't heard of any Dojo specific libraries similar to Mockjax. But what I think you could try is use Mockjax with Dojo. This should be pretty easy to do since all you'll have to do is use JQuery during development only for testing with Mockjax and then remove it once development is complete.
I use your second suggestion. Currently, I have a transport layer (simple js class) and 2 implementations (XhrTransport and MockTransport). I then switch in which I need without changing the widget code.
Widgets call the server with:
Controller.send(aServerCall);
where aServerCall is a simple value object with the server endpoint, params and callback.
This way, you can add nice things to the controller that will apply to all server calls (such as logging, analytics, generic error handling...) and also mock out the entire server when doing unit tests.
For the MockTransport, I simply return canned json data from static .js files in the format that the widget expects.