Hello I am using beego to create an API, and I am using gorillla for the session as I had problems with beego's session. Now this is working well on localhost but cookies are not sent on the deployed version on heroku.
Here is how I set the cookies in a controller:
session, _ := store.Get(c.Ctx.Request, "session") // c is the controller
session.Values["id"] = user.Id
Related
I'm developing a spring-boot based backend app and an angularjs based frontend app hosted on the same domain with different subdomains.
myapp-frontend.mydomain.com //my angularjs app
myapp-backend.mydomain.com //my spring-boot app
otherapp-frontend.mydomain.com //some existing app running on same domain but unrelated
I'm trying to set the cookie which contains the jwt token generated in the backend to the browser when login api is called from the angularjs.
Cookie is set into browser with this code when I set the base domain url in spring-boot:
Cookie cookie = new Cookie("Authentication", jwt);
cookie.setPath("/");
cookie.setDomain("mydomain.com"); //this works
response.addCookie(cookie);
This set the cookie for other apps hosted on our company domain, but doesn't share user credentials with my app. Since I want the Authentication cookie header to be visible only to my frontend app, I tried to set the frontend subdomain url in the code. But this doesn't work.
...
cookie.setDomain("myapp-frontend.mydomain.com"); //not setting cookie
...
I understand that cookie cannot be set across different domains for security reasons but why is setting the subdomain url not working?
Out of curiosity, I tried putting backend subdomain in the setDomain() and cookie is set under myapp-backend.mydomain.com when I checked in chrome developer tools. Since it's working with base domain url, I believe I have already implemented the CORS correctly.
Am I missing something here? Any input would be greatly appreciated.
I have .NET solution where there are two applications.
solution
APP1
APP2
APP1 and APP2 has different APP Pools in IIS.
APP1 contains actual website where it has client ,server side code and signalR.
APP2 is a web API built in ASP.NET WEB API 2.2.
From APP2 I am Posting data to APP1 server side code and data is brocasted using SignalR among users by pushing content to client side code.
ideally ,WEB API's data should reach users instanstly however in my case APP1 needs refresh and it takes time.
below is the code in APP1 To push content to client side.
' SignalR Update all feeds in the list
Dim HubContext As IHubContext = GlobalHost.ConnectionManager.GetHubContext(Of ActivityFeedHub)()
For Each ID As Integer In Feeds
Dim result As Object = New With
{
.Success = True _
, .Action = action.ToString() _
, .ActivityFeedProfileID = feedID _
, .UrlToReplace = DBSystem.Current.Subsites.HomeSite.URL
}
output.Remove("Result")
output.Add(New JProperty("Result", JObject.FromObject(result)))
' Send the update to client
HubContext.Clients.Group(ID).updateActivity(output.ToString())
I am new to SignalR any idea where i need to look up?
Any help or redirection will be highly appreciated!
Thanks!
You can't push data with SignalR from one app to clients connected with other app. Instead you should send data from one app to other app on server then each app will push same data with SignalR to its connected clients.
I am using ServiceStack as base library in one of my project.
I have structured my application in two part API and WEB application which are separate project and repository.
Authentication should happen on the API layer and it should be cached there. I am using Ormlite cache client in API Server.
In API AppHost.cs
var dbFactory = new OrmLiteConnectionFactory("ConnectionString",SqlServerDialect.Provider);
container.RegisterAs<OrmLiteCacheClient, ICacheClient>();
container.Resolve<ICacheClient>().InitSchema();
Plugins.Add(new AuthFeature(() => new APISession(),
new IAuthProvider[] {
new APICredentialsAuthProvider(new AppSettings())
}));
In APICredentialsAuthProvider i am saving session which gets stored in Db in CacheEntry table
I am authenticating the user in Web application via ajax call using apiurl/auth which return the AuthenticateResponse with sessionId with it.
I am updating this sessionId to cookie as s-id and later in pre request filter based on the request type it is being updated in ss-id or ss-pid.
//Inside Web application apphost
this.PreRequestFilters.Add((req, res) =>
{
System.Net.Cookie cookie = req.Cookies["s-id"];
req.Cookies["ss-id"] = cookie;
req.SetSessionId(cookie.Value)
});
This approach does not fetch the session from cache which is Ormlite in my case and respective configuration in provided in Web and Api application.
What is the best way to achieve this?
However i am able to access the session by using cache client
//Inside Web application apphost
this.PreRequestFilters.Add((req, res) =>
{
System.Net.Cookie cookie = req.Cookies["s-id"];
req.Cookies["ss-id"] = cookie;
req.SetSessionId(cookie.Value);
APISession cachedSession = GetCacheClient(req).Get<APISession(SessionFeature.GetSessionKey(cookie.Value));
WEBSession session.PopulateWith<WEBSession, APISession>(cachedSession);
});
this works fine and i am able to fetch the session, but by putting this in pre request filter increases the db calls from my web application (on each request).
Is there any alternate solution available to achieve the same?
Thanks in advance!!
If you are load balancing multiple Web Apps behind the same domain then using any of the distributed Caching Providers like OrmLiteCacheClient will send ServiceStack's ss-id/ss-pid Cookies when making a request to either of the Apps:
http://example.org/app1 -> http://internal:8001/
/app2 -> http://internal:8002/
/app3 -> http://internal:8003/
Then as long as each app is configured with the same OrmLiteCacheClient a Session created in one App would be visible in all 3 Apps.
You can prevent further DB access for retrieving the Session for that request by setting it on IRequest.Items, e.g:
req.Items[Keywords.Session] = session;
Then any access to the Session for that Request will be resolved from the IRequest Items Dictionary instead of hitting the DB.
Another alternative Auth solution that will let you authenticate in all 3 Apps is to use the stateless JWT Auth Provider.
I'm having application with running good in codeigniter, mysql and jquery. Currently we are planning to evaluate our web application with mobile application. So we planned to develop web application, android, ios and blackberry. Everything is native application.
For everything we planned to develop codeigniter restful API (This is server for all the client web and mobiles).
For web application we planned to develop client with angular js. But every client access web api server only. My codeigniter controller now looks like API.
My question is,
1.Is this good idea to create single server for all the client both web and mobile
2.How to create unique authentication for both web and mobile apps
Because in web app we have the session but in mobile there is no session. So how to create authentication uniquely for both apps.
I have planned to send a token to client, once login get successful. And then after for each and every request to server, the client will send a token with the request header. I have no idea of how to do the same for mobile apps, as web app having session, and hence we can save the token into session variable in server. But in-case of mobile app, how to create server variable and maintain the tokens.
Please anyone help me to get clarify my doubts.
You can check out Codeigniter REST Controller
(https://github.com/chriskacerguis/codeigniter-restserver/tree/master/application). It has different methods POST, GET etc
For Authentication:
If a server get a login request, if the login parameters are valid allow the user to login, at the same time update the user db column with a session id (this is not php session id) - create a session with user id+time+some random string sha 1 or some other encryption. And valid this session with all other request.If session is not matching the services return invalid session message.
If a server get a login request from a user even if there is session exist, regenerate the session and update corresponding column in db, this will make previous session invalid.
And also, we can share a API KEY (known to developer of web and app) as http header parameter. If API key matches then only the request proceeds. The mentioned codeigniter controller has the option to set API key.
Hope it is clear..
<?php
class Api_ci extends CI_Controller
{
public function __construct()
{
parent::__construct();
$this->load->model('Api_model');
$this->load->helper('text');
}
// code for login *api*-------------------------------
public function login_api_ci(){
$email = $this->input->get('email');
$pass = $this->input->get('password');
$query = $this->Api_model->login_api($email,$pass);
echo json_encode($query);
}
}
?>
<?php
class Api_model extends CI_Model{
public function __construct()
{
parent::__construct();
// Your own constructor code
$this->load->database();
}
// code for login api
public function login_api($username,$password){
$query = $this->db->query("SELECT * FROM `host_users` WHERE `email` = '$username' AND `password` = '$password'");
return $query->result_array();
}
}
?>
After these process, your API URL your domain name and / class name, class function:
www.example.com/Api_ci/login_api_ci?email=gaurav#gmail.com&password=1234567899
Output like this :
[{"id":"112","f_name":"gaurav","l_name":"singh","email":"gaurav#gmail.com","mob":"1234567899","password":"1234567899","img":null}]
Just to update this thread, I feel like creating a RESTFUL web API using Codeigniter is overkill, there's a lot of things that are unnecessary unless you are building a monolith system.
I prefer just creating a simple API without framework is better and lighter, it can also easily be scaled because nowadays microservices has more benefits than a monolith type of development.
I am using CodeIgniter framework at server side to provide backend to a native mobile app. At server side I have to use cart. I am using db for sessions in CodeIgniter. When we use sessions then session_id in cookie of browser let the session work. Mobile app retrieves the session ID from server response after login request is successful - then this session_id can be sent from mobile app to the server in further requests.
Now is there a way in CI to get the data of session on the basis of sessionid? Like if mobile app sends session_id 'xyz' then how can I get the data of session whose session_id is 'xyz'? And how it will be better to work with the session while using cart with it?
Following is my login code. Sessions are being stored in ci_session table of db.
function login($username,$password){
$query = $this->db->select("id,username")->get_where(self::$table, array('username' => $username,'Password'=>$password));
$arr=$query->row_array();
if($arr){
$this->session->set_userdata(array('id'=>$arr['id'],'username'=>$arr['username']));
// $this->db->insert('ci_sessions',array('user_id'=>$arr['id'],'username'=>$arr['username']));
return $this->session->userdata('session_id');
}
return 0;
}
So how can I get session w.r.t. session_id and how can cart work with it? Because I think as in this document: http://codeigniter.com/user_guide/libraries/cart.html cart automatically stores content against loaded session. Therefore I need to load session according to session_id so I can use CIs cart library correctly.
How can I load the session based on session_id, or tell me if I am doing it in a bad way?
First of all, the Question is very bad formatted and written down thus not very understandable...
If I understand it right, here is what You get:
in mobile native app user logs in - a request to a CI based server
CI server logs user in, saves data to session and saves session to the DB while responding to mobile app with session ID
mobile app then sends the session ID whenever a request is send to the server (like when using a cart)
Now - if You have the session stored in the database table ci_session, You only need to request the contents of session stored in the DB table based on session ID provided, so using Your login script example I would do sth similar:
function loadSessionBySessionId($sessionId){
$query = $this->db->select("*")->get_where('ci_session', array('session_id' => $sessionId));
return $query->row_array();
}
Extend the code to meet Your coding convention and server side application. Somewhere else at the server side application where You process the request from mobile app You will check whether the session is returned or not (if no, a FALSE should be returned) and take further actions...
Don't know how Your cart is working - this part is just upon You (unless You make it clear to us what You want us to help You with Your cart).