Log in to a Site by Bash

Shell Script to login into a website

If what you want to do is retrieve content from a website using HTTP Basic authentication then you can achieve this from the command line using wget or curl:

wget --http-user=user --http-password=password 

curl http://username:password@website.com/url

If cookie-based authentication is used you may be able to use wget for this too, depending on how it is set up. If for example you can HTTP POST to the login page

wget --save-cookies cookies.txt --post-data \
'user=myusername&password=mypassword' http://url/loginpage

wget --load-cookies cookies.txt -p http://url/thecontentIwant

The --save-cookies and --load-cookies allow for cookie-based authentication tokens to persist between requests.

If the form of authentication being used is more complex then the answer is going to be quite different - so it would help to state which website you have in mind. Furthermore, many sites have APIs that you should use instead...

In general it would help if you could clarify the question a little -- I find this bit 'at the same time I want to automatically take the user id and the password also' a bit confusing. If you want to do an interactive session in bash (i.e. getting the user to input username and password into the bash script) then you will find

read -e -p 

very useful (eg. read -e -p "My prompt: " varname; echo $varname).

Log in to a site (Stack Overflow) by Bash

For fun only: Connection: keep-alive

Introduction

My goal was to build a Bash environment where the current console (or script) could deal interactively with an authenticated HTTPS session. This could be used to address lot of IoT targets, address any provider platform to monitor personal account, etc.

Unfortunately, this could be badly used for stressing or hacking web platforms (targeting anyone) or even to targeting Stack Overflow's Fanatic badge (dirty cheater!).

My apologies for any bad use of this. Anyway, I'm not responsible of what people do.

Near pure Bash: require only OpenSSL:

... and gpg, but you're free to store your credential in another way.

Preparing some values:

#!/bin/bash
shopt -s extglob

URL='https://stackoverflow.com/'
IFS=: read -r user pass < <(gpg -qd <socred.gpg)

IFS=/ read -r _ _ hst _ <<<"$URL"

Running the OpenSSL executable as a background task:

exec {wwwE}<> <(: - O)
exec {wwwI}<> <(: - b)
exec {wwwO}< <(
exec stdbuf -o0 openssl s_client -quiet -connect "$hst":443 <&$wwwI 2>&$wwwE)
osslpid=$!

Then now, there is a little doReq function to create two variables: $cookie and $htstatus, and three arrays: $hthead, $htbody and $hterr:

doReq() {
hthead=() htbody=() hterr=()
local target=$1 method=${2:-GET} head=true line cookies
printf >&$wwwI '%s\r\n' "$method $target HTTP/1.1" "Host: $hst" \
"User-Agent: aobs/0.01" "Connection: keep-alive" "Accept: */*"
[ "$cookie" ] && printf >&$wwwI '%s' "$cookie"
if [ "$method" = "POST" ];then
printf >&$wwwI '%s\r\n%s\r\n\r\n%s' "Content-Length: ${#3}" \
'Content-Type: application/x-www-form-urlencoded' "$3"
else printf >&$wwwI '\r\n'
fi
read -t 10 -ru $wwwO line
htstatus=${line%$'\r'} ; hthead=("$htstatus")
while read -t .3 -ru $wwwO line;do
[ "${line%$'\r'}" ] || head=false;
if $head ;then
hthead+=("${line%$'\r'}");
case $line in
[sS]et-[cC]ookie:* ) line=${line#*: };
cookies+=("${line%%;*}");;
esac
else htbody+=("${line%$'\r'}") ;fi
done
if read -t 0 -ru $wwwE;then
while read -t .1 -ru $wwwE line;do
hterr+=("${line%$'\r'}")
case $line in
depth* | verify* ) ;;
* ) echo "ERR: $line" ;;
esac ; done ; fi
[ ! -v "cookie" ] && [ "${cookies[0]}" ] &&
printf -v cookie 'Cookie: %s\r\n' "${cookies[@]}"
}

Usage: doReq /file_part_of_URL [method] [post datas]

Let's login:

doReq /users/login POST "email=$user&password=$pass"

Now show my badges:

doReq /
for ((i=${#htbody[@]};i--;)) ;do
line="${htbody[i]}"
case $line in
*badge1* ) line="${htbody[i-1]}${htbody[i]}${htbody[i+1]}"
line=${line//>+([0-9])</><} line=${line//<*([^>])>}
printf '%b\n' "${line//●/ \\U25cf }" ;;
esac ; done

On my desk, with my account, this prints:

 ● 13 gold badges ● 88 silver badges ● 112 bronze badges

(just now).

Of course, you're now ready to run doReq any time you like, as the connection stays open. We are now in environment/condition cited in the Introduction. (The version on my site does a forever loop, requesting this in a more efficient way, each rounded two minutes (EPOCHSECONDS % 120), up to user interaction. See at the bottom of this.)

...

Once you're done, before exit, you could stop openssl and close your file descriptor:

(I've added ls and ps as debug commands.)

ls -l /dev/fd/ ; ps --tty $(tty) ufw
kill $osslpid
exec {wwwE}<&-
exec {wwwI}>&-
exec {wwwO}<&-
ls -l /dev/fd/ ; ps --tty $(tty) ufw

This shows:

total 0
lrwx------ 1 user user 64 jui 2 13:52 0 -> /dev/pts/2
l-wx------ 1 user user 64 jui 2 13:52 1 -> /dev/pts/2
lrwx------ 1 user user 64 jui 2 13:52 10 -> pipe:[940266653]
lrwx------ 1 user user 64 jui 2 13:52 11 -> pipe:[940266654]
lr-x------ 1 user user 64 jui 2 13:52 12 -> pipe:[940266655]
lrwx------ 1 user user 64 jui 2 13:52 2 -> /dev/pts/2
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
user 28110 0.0 0.0 11812 7144 pts/7 Ss jui01 0:02 bash
user 14038 30.0 0.0 9116 4228 pts/7 S+ 13:52 0:00 \_ /bin/bash ./getSo.sh
user 14045 0.5 0.0 9356 5856 pts/7 S+ 13:52 0:00 \_ openssl s_client -quiet -connect stackoverflow.com:443
user 14048 0.0 0.0 12404 3400 pts/7 R+ 13:52 0:00 \_ ps --tty /dev/pts/7 ufw

total 0
lrwx------ 1 user user 64 jui 2 13:52 0 -> /dev/pts/2
l-wx------ 1 user user 64 jui 2 13:52 1 -> /dev/pts/2
lrwx------ 1 user user 64 jui 2 13:52 2 -> /dev/pts/2
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
user 28110 0.0 0.0 11812 7144 pts/7 Ss jui01 0:02 bash
user 14038 30.0 0.0 9632 4756 pts/7 S+ 13:52 0:00 \_ /bin/bash ./getSo.sh
user 14051 0.0 0.0 12404 3332 pts/7 R+ 13:52 0:00 \_ ps --tty /dev/pts/7 ufw

The OpenSSL process is done and all three file descriptors become closed.

You could find this script (less condensed), with an extended main loop at getSo.sh.txt, getSo.sh.

a script to log into webpage

Take a look a cURL, which is generally available in a Linux/Unix environment, and which lets you script a call to a web page, including POST parameters (say a username and password), and lets you manage the cookie store, so that a subsequent call (to get a different page within the site) can use the same cookie (so your login will persist across calls).

bash script to login to webpage

Some things you're obviously doing wrong - your form looks like this:

<form onsubmit="return validate_form(this)" method="post" action="https://bb5.fsu.edu/cas/" id="login" AUTOCOMPLETE="off">
<!-- etc -->
</form>

You need to submit your request to the "action" URL of the form, and you need to make it a POST request instead of a GET request to some other URL.

a script to log into webpage

Take a look a cURL, which is generally available in a Linux/Unix environment, and which lets you script a call to a web page, including POST parameters (say a username and password), and lets you manage the cookie store, so that a subsequent call (to get a different page within the site) can use the same cookie (so your login will persist across calls).



Related Topics



Leave a reply



Submit