in reply to Re: Integrating Perl cgi forms with Drupal site, any advise on unified login issue?
in thread Integrating Perl cgi forms with Drupal site, any advise on unified login issue?

Dear brothers!

A few days ago I met with the task to find anything on this issue, but alas - not found!

Site where for many years I developed some system (axis) by Pearl moved from SSI layout and Ikonboard 2.7 for Drupal 7 and there is a need to ensure that authorized in the Drupal client could then log in axis (and get the appropriate right).

Both systems are on the same domain, and axis has access to a database (MySQL) Drupal 7.

I have found that when authorizing, Drupal 7 records 1 cookie to the browser. This - the parameters of the session. Tricky :) Name:

Example: SESS4cd3a9072f7dd0a7d016dd7437bbebcb

and no less tricky :) value:

Example: UuouTLxPISffp0enDQQpHrJQmKIgWgMGmJqrURICX7A

These cookies are the keys to verify the user's authorization in the system Drupal,

Must work so I decided to:

1. The customer is always authorized in one place - in Drupal.
2. Each time of run perl script checks the user logged in Drupal or not, and if - yes - run further execution and reporting the user into my perl script.

Code is supposed to operate according to the following algorithm

1. Launch

2. The definition of a domain name and directory location of Drupal

3. The calculation of the cookie name on the algorithm

4. Read cookies value from browser by this name

5. Identification of the value of the cookie - id authorized user with a SQL query to a database table Drupal. Having id - get the right and login. Next, it is clear that to do with it.

Found:

of parsing Drupal 7 code library :

 \includes\bootstrap.inc line 784

784 ......... session_name ($prefix.substr(hash('sha256', $session_nam +e), 0, 32));

Cookie name is computed as follows:

first part - it SESS or SSESS - depending on the protocol by which authorization is Drupal: http or https is selected for authorization, in this case, $prefix.

second part: digest (hash) of the domain name and the folder where you installed Drupal, clipped to the first 32 characters ..
For example, if Drupal is installed in the folder with url:
http://snowpro.ru/drupal/, computed digest of "snowpro.ru /drupal", if http://snowpro.ru/, computed digest of "snowpro.ru"

Once we have identified the name of the cookie we can read the value of this cookies, by standard perl function, and then find for user id by the value of cookies in sessions table of Drupal. The value of cookie - is the session id.

That's It!

.... $data = $drupal_host; #drupal domane name $dig=&digest_sha($data); #hash of domane name $sesionname='SESS'.substr($dig, 0, 32); $ssesionname='SSESS'.substr($dig, 0, 32); $valuecook = cookie($sesionname); $valuecook_s = cookie($ssesionname); # #!!! do not forget to check $valuecook_s to safe from $sql injection # &dbopen_d; #my sub to open db # $d_u_t - drupal user table # $d_ur_t - drupal user roles table # $d_r_t - roles table $sql=qq~SELECT $d_u_t.name, $d_ur_t.rid FROM $d_s_t, $d_u_t, $d_ur_t, $d_r_t WHERE ($d_s_t.sid="$valuecook" OR $d_s_t.ssid="$val +uecook_s") AND $d_ur_t.uid=$d_u_t.uid AND $d_s_t.uid=$d_u_t.uid AND $d_u_t.login<UNIX_TIMESTAMP() AND ( UNIX_TIMESTAMP() - $d_s_t.timestamp )<8 +6400~; my $sth = $dbh->prepare($sql); my $rv=$sth->execute or die "xxx" ......

sub digest_sha{ use Digest::SHA qw(sha256_hex); my ($data)=@_; $digest1 = sha256_hex($data); return $digest1; }

I would be grateful for comments and suggestions.

Replies are listed 'Best First'.
Re^3: Integrating Perl cgi forms with Drupal site, any advise on unified login issue?
by Anonymous Monk on May 27, 2013 at 07:27 UTC

    I would be grateful for comments and suggestions.

    um, make it a module, a kwalitee module with documentation, that describes what it does , say something along the lines of

    # is_user_valid( # is_user_loggedin( # is_user_user( # is_user( is_authenticated_drupal( dbi => $dbi, cookie => $cookie, ); # can_user_do_this( # is_user_allowed_to( is_authenticated_drupal( dbi => $dbi, cookie => $cookie , page => $page, section => $section, something_else => $something, );

    But maybe you want to make it a CGI::Session::Auth plugin so you'd suit the interface to boot

    But not having done anything DRUPAL, I'm not even sure this is the best way (raw SQL access) -- I can't imagine that drupal doesn't have an official api independent of backend for authorentication/authorization

      Thank you for your answer, maybe one day be a module

      I probably did not quite understand the last about Drupal API.
      It's possible to send POST with username and password and receive an answer with user data ...
      but then I myself have to check my cookie security by my system.
      They need to generate, store, watch out if they are out of date, etc. It's harder, I think?
      Perhaps this is the solution for those cases when the systems are in different servers.
      But then an additional security risk?

        I don't think you get my meaning. Consider
        my $exitcod_zero_means_something = system '/usr/local/bin/drupal_fun_authenticator', '--cookie=cookie', ... ;;;;; ### or sub is_authorized { my ( $authcookie, ... ) = @_; my $wget = join ' ', map { "'$_'" } "--header=cookie:$authcookie", 'https://localhost:3000/hey_drupal_authenticate_by_cookie', ... ;;;;; my $json_auth_str = qx{wget $wget } my $auth = decode_json( $json_auth_str ); return 1 if $auth->{is_authorized}; return 0; }

        drupal, being so popular and what not, surely has such an interface -- I'd go looking for it -- official API is safer than peeking into the database

      @dimuse_dioplut Thank you for making the code available to the public in perlmonks- it is proving to be useful for me. Have you created a module yet out of the code you posted?
        Welcome "Have you created a module yet out of the code you posted?" No. It seems it will be not soon. Sorry.