I'm attempting to set up an authorization process through the Box-Api. The first step has to be a GET call to the authorization URL, It has to carry three parameters:
Redirect_url
Client_id
Response_type=Code
This is my sample code for this call:
class OauthController extends Zend_Controller_Action
{
public function indexAction()
{
$client = new Zend_Http_Client('https://www.box.com/api/oauth2/authorize');
$client->setMethod(Zend_Http_Client::GET);
$client->setParameterGet(array(
'response_type' => 'code',
'client_id' => 'xxxxxxxxxxxxxxxxxx',
'redirect_uri' => 'http://localhost/imball-reagens/callback'
));
$response = $client->request();
$this->_helper->viewRenderer->setNoRender(true);
return $response;
}
}
I've made a link in the homepage of my website to this controller, and i've taken away the view so the Controller can do only the http call. It should propt the user with the login of Box.com, but it doesn't, instead it only shows a white page.
Zend server throws a warning when i call this controller:
Slow Request Execution
Request to http://localhost:10088/imball-reagens/public/oauth took 3042ms
The procedure has to be written in a link in the homepage. This an example:
Authorize Account Box API
Related
I configured and initialized AWS Amplify for my ReactNative/Expo app and added a REST Api. Im new to AWS in general, but im assuming that once I add the API, my project is populated with amplify/backend folders and files and is ready for consumption.
So i tried to create a simple post request to create an item in my DynamoDB table with
import { Amplify, API } from "aws-amplify";
import awsconfig from "./src/aws-exports";
Amplify.configure(awsconfig);
const enterData = async () => {
API.post("API", "/", {
body: {
dateID: "testing",
},
headers: {
Authorization: `Bearer ${(await Auth.currentSession())
.getIdToken()
.getJwtToken()}`
}
})
.then((result) => {
// console.log(JSON.parse(result));
})
.catch((err) => {
console.log(err);
});
};
const signIn = async () => {
Auth.signIn('test#test.com', 'testpassword')
.then((data) => {
console.log(data)
enterData() //enterData is attempted after signin is confirmed.
})
.catch((err) => {
console.log(err)
})
}
signIn()
I did not touch anything else in my project folder besides including the above in my App.tsx because im unsure if i need to and where. I got a 403 error code and it "points" to the axios package but im not sure if issue is related to aws integration.
I configured the REST Api with restricted access where Authenticated users are allowed to CRUD, and guests are allowed to Read. How could I even check if I am considered an "Authorized User" .
Yes, AWS Amplify API category uses Axios under the hood so axios is related to your problem.
Probably you get 403 because you didn't authorized, for Rest API's you need to set authorization headers,
I don't know how is your config but you can take help from this page. Please review the "Define Authorization Rules" section under the API(REST) section.
https://docs.amplify.aws/lib/restapi/authz/q/platform/js/#customizing-http-request-headers
To check authorization methods, you can use "Auth" class like that also you can see auth class usage in the above link.
import { Amplify, API, Auth } from "aws-amplify";
https://aws-amplify.github.io/amplify-js/api/classes/authclass.html
in a web app we have used 2 Auth methods
default is JWT which we are using for API’s
but for website we are using session
somehow session are not destroying on logout
i can still access session by
auth.authenticator('session').getUser()
even after this doing in logout
await auth.authenticator('session').logout()
Here is my full code for login
Route.get('/login', async ({ view ,auth,response}) => {
try{
await auth.authenticator('session').check()
response.route('/feed')
}
catch(e){
return view.render('user.login') // User login page in web
}
})
Logout route
Route.get('/logout', async ({ auth, response }) => {
await auth.authenticator('session').logout()
response.route('/login')
})
i have noticed that if i disable chrome cache from dev tools then web app works fine
I create a app thet need to implement authentification with email/password on all pages except one page (mobile_messages), where need to authenticate with refresh token.
I extend from JWT authenticator and override authenticate method. So it looks like:
authenticate (credentials, headers) {
return new Ember.RSVP.Promise((resolve, reject) => {
this.makeRequest('/auth/mobile_token', credentials, headers)
.then((response) => {
Ember.run(() => {
try {
const sessionData = this.handleAuthResponse(response)
resolve(sessionData)
} catch (error) {
reject(error)
}
})
}, (xhr) => {
Ember.run(() => { reject(xhr.responseJSON || xhr.responseText) })
})
})
}
On mobile_messages route I try to authenticate in before model hook.
beforeModel (transition) {
const authenticator = 'authenticator:api-token'
return this.get('session').authenticate(authenticator, {api_token: transition.queryParams.api_token}).then(() => {
}, (reason) => {
transition.abort()
this.get('notifications').error('Permission denied.', {
autoClear: true,
clearDuration: 6200
})
})
},
I need to stay on mobile_messages route if authenticate rejected. But when I enter to route with wront token I got next backtrase:
Preparing to transition from '' to 'mobileMessages'
index.js:169 generated -> controller:mobileMessages {fullName:
"controller:mobileMessages"}
index.js:169 generated -> controller:aut`enter code here`henticated
{fullName: "controller:authenticated"}
index.js:169 generated -> controller:loading {fullName:
"controller:loading"}
router.js:300 Intermediate-transitioned into 'authenticated.loading'
index.js:169 generated -> route:messages-faxes {fullName:
"route:messages-faxes"}
router.js:190 Transitioned into 'login'
jquery.js:9600 POST http://localhost:3000/auth/mobile_token 500
(Internal Server Error)
It looks like I was redirected before got response from server. An I can't find who is redirect me from route. I try to check ApplicationRouteMixin but i got that sessionInvalidated method calls only if you click logout button. And sessionAuthenticated after success authentification.
If I push to route correct token, then I first redirect to login page and then sessionAuthenticated fires. After that i redirect to baseURL.
Hot to solve issue with redirection to login page?
Ember Simple Auth uses Mixins to determine the route transition behavior that should happen if a user is authenticated/unauthenticated.
For example, this mixin will not allow the user to stay on the route if they are unauthenticated:
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';
export default Ember.Route.extend(AuthenticatedRouteMixin, {
// route code
});
What you probably want to use is the UnauthenticatedRouteMixin
This mixin is used to make routes accessible only if the session is
not authenticated (e.g., login and registration routes). It defines a
beforeModel method that aborts the current transition and instead
transitions to the routeIfAlreadyAuthenticated if the session is
authenticated.
Include UnauthenticatedRouteMixin in your routes, which needs to accessed if the session is not validated. For example:
// app/routes/login.js
import UnauthenticatedRouteMixin from 'ember-simple-
auth/mixins/unauthenticated-route-mixin';
export default Ember.Route.extend(UnauthenticatedRouteMixin);
It was an error with loading hook. I make an error with naming routes. I created route with name loading to redirect to messages-faxes route. In this case when before model hook return promise ember generate route:application_loading. In application_loading route I run transition to messages-faxes route which has UnauthenticatedRouteMixin. This mixin see that user is not Authenticated and redirect to loading page.
I have the following situation: The user enters his credentials and clicks a Login button. An API call is done in the action creator via redux-thunk. When the API call was successful, another action is dispatched containing the response from the server. After the (successful) login I want to store the users session id in a cookie (via react-cookie).
Action creator
export function initiateLoginRequest(username, password) {
return function(dispatch) {
dispatch(loginRequestStarting())
return fetch('http://path.to/api/v1/login',
{
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
username: username,
password: password
})
})
.then(checkStatus)
.then(parseJSON)
.then(function(data) {
dispatch(loginRequestSuccess(data))
})
.catch(function(error) {
dispatch(loginRequestError(error))
})
}
}
export function loginRequestSuccess(user) {
return {
type: ActionTypes.LOGIN_REQUEST_SUCCESS,
user
}
}
Reducer
export default function user(state = initialState, action) {
switch (action.type) {
case ActionTypes.LOGIN_REQUEST_SUCCESS:
cookie.save('sessionId', action.user.sid, { path: '/' })
return merge({}, state, {
sessionId: action.user.sid,
id: action.user.id,
firstName: action.user.first_name,
lastName: action.user.last_name,
isAuthenticated: true
})
default:
return state
}
}
Right now the reducer responsible for LOGIN_REQUEST_SUCCESS saves the cookie. I know the reducer has to be a pure function.
Is saving a cookie in the reducer violating this principle? Would it be better to save the cookie inside the action creator?
Have a look at redux-persist.
You can persist/save your reducers (or parts of them) in LocalStorage.
Concept
Initiate login.
Receive cookie from server.
Dispatch login success.
Reducer stores cookie in memory.
Persist middleware stores reducer state in LocalStorage.
Example
Install
npm install --save-dev redux-persist
Example Usage
Create a component that wraps the persistence/rehydration logic.
AppProvider.js
import React, { Component, PropTypes } from 'react';
import { Provider } from 'react-redux';
import { persistStore } from 'redux-persist';
class AppProvider extends Component {
static propTypes = {
store: PropTypes.object.isRequired,
children: PropTypes.node
}
constructor(props) {
super(props);
this.state = { rehydrated: false };
}
componentWillMount() {
const opts = {
whitelist: ['user'] // <-- Your auth/user reducer storing the cookie
};
persistStore(this.props.store, opts, () => {
this.setState({ rehydrated: true });
});
}
render() {
if (!this.state.rehydrated) {
return null;
}
return (
<Provider store={this.props.store}>
{this.props.children}
</Provider>
);
}
}
AppProvider.propTypes = {
store: PropTypes.object.isRequired,
children: PropTypes.node
}
export default AppProvider;
Then, in your index.js or file in which you set up the store, wrap the rendered components in your new AppProvider.
index.js
...
import AppProvider from 'containers/AppProvider.jsx';
...
render((
<AppProvider store={store}>
...
</AppProvider>
), document.getElementById('App'));
This will serialize your user reducer state to LocalStorage on each update of the store/state. You can open your dev tools (Chrome) and look at Resources => Local Storage.
I'm not sure if this is the "right" way, but that's how my team is persisting the logged user in the Redux app we built:
We have a very default architecture, an API ready to receive requests in one side, and a React/Redux/Single Page app that consumes this API endpoints in the other side.
When the user credentials are valid, the API's endpoint responsible for the login respond to the app with the user object, including an access token. The access token is latter used in every request made by the app to validate the user against the API.
When the app receives this user information from the API two things happen: 1) an action is dispatched to the users reducer, something like ADD_USER, to include this user in the users store and 2) the user's access token is persisted in the localStorage.
After this, any component can connect to the users reducer and use the persisted access token to know who is the logged user, and of course if you have no access token in your localStorage it means the user is not logged in.
In the top of our components hierarchy, we have one component responsible to connect to the users reducer, get the current user based on the access token persisted in the localStorage, and pass this current user in the React's context. So we avoid every component that depends on the current user to have to connect to the users reducer and read from the localStorage, we assume that this components will always receive the current user from the app's context.
There are some challenges like token expiration that adds more complexity to the solution, but basically this is how we are doing it and it's working pretty well.
I'd probably have the server-side set the cookie, personally, and make it transparent to JavaScript. But if you really want to do it client-side, I'd do it in an action helper. Something like this:
// Using redux-thunk
function login(user, password) {
return dispatch => api.auth.login(user, password)
.then(result => setCookie())
.then(() => dispatch({type: 'USER_LOGGED_IN'}))
}
Or something like that.
Action helpers don't need to be pure, but reducers should be. So, if I'm doing side-effects, I put them into action helpers.
I'm trying unit testing in Laravel 5. I followed this answer and got it half working. I've made it so that user is always redirected to the login page if not authenticated. Once authenticated, the home page should be the base url. The test for redirecting to the login page passes, but the test for showing home page when the user is authenticated doesn't:
Expected status code 200, got 500.
If I login in the browser I get the home page just fine. Why is that?
routes.php
Route::get('/', 'HomeController#index');
Route::controllers([
'auth' => 'Auth\AuthController',
'password' => 'Auth\PasswordController',
]);
my tests
/**
* This test passes. You get redirected if no user is authenticated
* #test
* #return void
*/
public function it_redirects_to_login_if_not_authenticated()
{
Auth::shouldReceive('check')->once()->andReturn(false);
$response = $this->call('GET', '/');
$this->assertFalse($response->isOk());
}
/**
* This test doesn't pass. The user is authenticated but the test fails
* 'Expected status code 200, got 500.'
* #test
*/
public function it_returns_home_page_if_user_is_authenticated()
{
Auth::shouldReceive('check')->once()->andReturn(true);
$this->call('GET', '/');
$this->assertResponseOk();
}
Can anyone help ?