1

In some developments for drupal 7, I need connect with one user via a bash script then get the content of the connected homepage.

After several searches, my last try :

URL="https://www.mainsite.com/subsiteone/"

curl -s -f -o $output -H "Content-Type:application/xml" --insecure  $URL  -w "@formatsender.conf"  > ./test.txt

formid=$( grep 'input type="hidden" name="form_build_id"' $output | cut -d"=" -f4 | sed -e 's/"//g' | sed -e 's/\/>//g' )
echo $formid #show the good pofm id

curl --request POST ${URL} --data "name=usernameone%26pass=userpasswordone%26form_build_id=$formid%26form_id=user_login"

the last curl shows the content of the login page (not connected) without any error message. I don't understand where is my mistake..

0

2 Answers 2

2
+25

You might want to double checking your encoding or the headers that you're sending over that might cause the problem. I've found trying to do this with a pure Bash solution very fickle at times. Here's an example function I've used that will login into a D7 site on the /user page (an easier manner since every D7 install can be logged in from that path).

#!/bin/sh

# https://gist.github.com/cdown/1163649
#Usage: urlencode "string"
function urlencode() {
  old_lc_collate=$LC_COLLATE
  LC_COLLATE=C

  local length="${#1}"
  for (( i = 0; i < length; i++ )); do
    local c="${1:i:1}"
    case $c in
      [a-zA-Z0-9.~_-]) printf "$c" ;;
      *) printf '%%%02X' "'$c" ;;
    esac
  done

  LC_COLLATE=$old_lc_collate
}

#Usage: login "user" "pass"
function login() {
  URL=https://www.example.com/user
  name=$(urlencode "$1")
  pass=$(urlencode "$2")
  post_data="name=$name&pass=$pass"

  #Retrieve login page, login form, & input fields.
  login_page=$(curl -s -H "Content-Type:application/xml"  "$URL")
  login_form=$(echo $login_page | grep -o '<form[^>]*action="/user"[^>]*id="user-login"[^>]*>.*</form>')
  login_input=$(echo $login_form | grep -o '<input[^>]*/>')

  #Create Post Body
  while read -r input; do
    input_field=$(echo "$input" | sed -e 's/.*name="\([^"]*\)".*/\1/')
    if [[ $input_field != "name" && $input_field != "pass" ]]; then
      input_value=$(echo "$input" | sed -e 's/.*value="\([^"]*\)".*/\1/')
      input_field=$(urlencode "$input_field")
      input_value=$(urlencode "$input_value")
      post_data="$post_data&$input_field=$input_value"
    fi
  done <<< "$login_input"

  # Depending on your hosting environment you might need additional headers to make yourself not look like a bot
  user_agent="User-Agent:Mozilla/5.0 "
  referer="Referer:https://www.example.com/user"
  origin="Origin:https://www.example.com"
  content_type="Content-Type:application/x-www-form-urlencoded"

  # For further authenticated requests, you will need to parse output "Set-Cookie: ..." and set
  # the session cookie in a -H "Cookie: ..." option
  curl -s -L -H "$content_type" -H "$user_agent" -H "$referer" -H "$origin" --request POST "${URL}?destination=/" --data "$post_data"
}

login 'USER' 'PASS'

I've found logging into Drupal via Bash much easier with if you can work with a scripting language that has built in HTTP clients & parsers. Depending on your scenario, you might want to consider that if you need a more robust solution.

4
  • thanks you ! I tested this script and I replace the 'USER' 'PASS' and 'URL' variables. But the curl returns nothing :/ May 23, 2016 at 9:00
  • I print the curl command before his execution. I didn't notice any problem ... I have : curl -s -L -H Content-Type:application/x-www-form-urlencoded -H User-Agent:Mozilla/5.0 -H Referer:mainsite.com/subsiteone/user -H Origin:mainsite.com/subsiteone --request POST mainsite.com/subsiteone?destination= --data "name=usernameone&pass=userpasswordone&=" May 23, 2016 at 9:11
  • When I remove the '-H Refere:..." parameter, curl return a page ! but this is (again..) the login page not connected May 23, 2016 at 9:23
  • I don't want to turn this is to a long debug convo so I'll mention 2 things. 1: Adjust the curl options (e.g. -v -s) to ensure the request is being made. 2: Make sure that a new session is created; check the sessions table or set the -v flag to check for the Set-Cookie: header; you can parse out the session key and added it to subsequent curl requests (e.g. -H 'Cookie: SSESS<HASH> = <SESSION>;) to request any page as an authenticated user.
    – Shawn Conn
    May 23, 2016 at 18:00
0

When you post the user credentials to Drupal, I am pretty sure you need to POST it to /user/login and not to the front page.

Then after loggin in, Drupal's default behavior is to redirect the user to /user, not the front page. You might succeed appending ?destination=<front> to the request path, use Rules to redirect the user after login, or use Login Destination to make sure the site will present you the front page.

You might want to try something like this for your last line:

curl --request POST ${URL}/user/login?destination=<front> --data "name=usernameone%26pass=userpasswordone%26form_id=user_login"

I believe form_build_id is not mandatory, but I am not really sure so you might have to add that. I omitted it in the example.

3
  • This is correct: Maybe the front page contains the login block, but the correct page to submit the login form is not that. Also, I assume Drupal needs to know which submission button has been pressed.
    – apaderno
    May 18, 2016 at 19:32
  • Thanks for your answer ! I tested with "curl --request POST ${URL}/user/login?destination=<front> --data "name=usernameone%26pass=userpasswordone%26form_id=user_login"" or with the form_build_id but the lhis curl always return me the login page without any error message :/ May 19, 2016 at 7:34
  • 1
    It might be due to that ${URL} ends with a slash (/) as well, so the url becomes https://www.mainsite.com/subsiteone//user/login?destination=<front>. Try removing one slash. Also check if https://www.mainsite.com/subsiteone/user/login in fact shows the login page. Finally, perhaps the ampersands in the query string don't have to be URL-encoded and you can use name=usernameone&pass=userpasswordone&form_id=user_login. But these are just guesses. May 19, 2016 at 8:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.